简体   繁体   English

弱委托和.xib文件

[英]Weak delegates and .xib files

Why are weak delegates not neeeded when using.xib files?为什么使用.xib 文件时不需要弱委托?

I made a simple project that doesn't use storyboards.我做了一个不使用故事板的简单项目。 It just uses.xib files associated with UIViewControllers.它只使用与 UIViewControllers 关联的.xib 文件。 It presents the user with a button that when pressed, pushes a new viewcontroller and allows them to go back.它为用户提供了一个按钮,当按下该按钮时,它会推动一个新的视图控制器并允许他们返回 go。 If the navDelegate below is listed as weak, then navigation to the DetailViewController never happens since navDelegate will always be nil.如果下面的 navDelegate 被列为弱,则导航到 DetailViewController 永远不会发生,因为 navDelegate 将始终为零。

SceneDelegate.swift SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?


    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let winScene = scene as? UIWindowScene else {
            return
        }
        window = UIWindow(windowScene: winScene)
        AppCoordinator().start()
    }
}

AppCoordinator.swift AppCoordinator.swift

import UIKit

protocol Coordinator: AnyObject {
    func start()
}

class AppCoordinator: Coordinator {
    let router = UINavigationController()

    func start() {
        let vc = RootViewController()

        vc.navDelegate = self
        router.viewControllers = [vc]
        let window = UIApplication.shared.windows.first
        window?.rootViewController = router
        window?.makeKeyAndVisible()
    }
}

extension AppCoordinator: NavDelegate {
    func buttonTapped() {
        let vc = DetailViewController()
        router.pushViewController(vc, animated: true)
    }
}

RootViewController.swift RootViewController.swift

import UIKit

protocol NavDelegate: AnyObject {
    func buttonTapped()
}

class RootViewController: UIViewController {

    // Does this navDelegate need to be weak when using .xib files?
    var navDelegate: NavDelegate?

    init() {
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func tapDetailButton(_ sender: Any) {
        // Always prints 2 no matter how many times I navigate back and forth
        let refCount = CFGetRetainCount(navDelegate)
        print("Ref Count: \(refCount)")
        navDelegate?.buttonTapped()
    }
}

DetailViewController.swift DetailViewController.swift

import UIKit

class DetailViewController: UIViewController {

    init() {
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

So with further insight from @matt, it seems that if you have the AppCoordinator as an instance variable of the SceneDelegate then having the navDelegate as weak works.因此,通过@matt 的进一步了解,似乎如果您将 AppCoordinator 作为 SceneDelegate 的实例变量,那么将 navDelegate 作为弱工作。 I suppose the mistake is calling the navDelegate a delegate.我想错误是将 navDelegate 称为委托。 It should just be called something like a navHelper so there's no confusion as to whether it should be weak or not.它应该被称为像 navHelper 这样的东西,所以对于它是否应该是弱的没有混淆。

Nothing to do with xibs.与xib无关。 Or delegates either, really.或者代表,真的。

If you know what weak means, you know that it means "If no one else is holding a strong reference to this thing, let it go out of existence."如果你知道weak是什么意思,你就知道它的意思是“如果没有其他人对这个东西持有强引用,让它 go 不存在。”

So when you say vc.navDelegate = self , where self in AppCoordinator instance, then if no other reference to this AppCoordinator instance retains it, it vanishes in a puff of smoke immediately afterward.因此,当您说vc.navDelegate = self时,其中self在 AppCoordinator 实例中,如果没有其他对此 AppCoordinator 实例的引用保留它,它会立即消失在烟雾中。

Well, what's the life story of this instance?那么,这个实例的生活故事是什么?

 AppCoordinator().start()

What does that line do?那条线有什么作用? It creates an AppCoordinator instance, calls start on it, and then drops the AppCoordinator on the floor, letting it go out of existence if no one else is holding on to it.它创建一个 AppCoordinator 实例,对其调用start ,然后将 AppCoordinator 放到地板上,如果没有其他人持有它,则让它 go 不存在。 And no one else is holding on to it, because the only reference that anyone else had to it was weak .没有其他坚持它,因为其他人对它的唯一引用是weak

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM