在整个区域重用UIViewController实例

时间:2016-04-23 10:59:41

标签: swift uiviewcontroller initialization thread-safety

这是我们的场景,我们有VC A,B和C.同样,我们有VC X.

我需要使用&在A,B和C中呈现VC X.

每次我在每个VC上时,我都不想重新创建一个实例。 所以基本上我在考虑在App Delegate创建全局实例/属性并在那里初始化它,并在需要时提供VC X.

 vcX = self.storyboard?.instantiateViewControllerWithIdentifier("IAP") as! newIAPClass

这是否会导致意外行为?

1 个答案:

答案 0 :(得分:1)

以下是重用viewController X的单个副本的一些想法:

  1. 线程安全应该与它无关,因为需要在主线程上执行所有用户界面交互

  2. viewController的每个实例一次只能有最多一个父。因此,只要您在视图层次结构中仅使用X一次,就应该没问题。例如,A表示呈现X的B,然后X返回到B,返回A.然后A表示呈现X的C.这样可以正常工作,因为X在任何给定时间只有一个父。

  3. 这样做意味着X会在演示文稿之间保留所有设置,因此演示者有责任清理并在演示前正确初始化它。通过保留X的永久全局副本,它将保留调用之间的所有数据。例如,如果存在输入文本字段,则该文本字段仍将包含先前使用的文本。演示者将负责重新初始化viewController X保留和使用的任何数据。这将包括一个委托指针。

  4. 可能导致问题的场景示例:A,B和C都包含在UITabBarController中。每个人都可以显示X,以便用户可以更改设置。如果A呈现X然后用户将标签切换到B然后再次呈现X,则会失败,因为现在X将同时具有A和B作为父母,这无法工作。

    不要将viewController NewIAPClass创建为全局,而应考虑将其设为 Singleton 。请参阅此答案:Creating a Singleton in Swift

    所以你要像这样创建NewIAPClass

    class NewIAPClass: UIViewController {
        static let sharedInstance = UIStoryboard(name:"Main", bundle:nil).instantiateViewControllerWithIdentifier("IAP") as! NewIAPClass
    
        // All of the other stuff that makes up NewIAPClass ...
    }
    

    然后,每当您想要使用NewIAPClass时,您都会将其称为NewIAPClass.sharedInstance