使用instantiateViewControllerWithIdentifier访问相同的视图控制器

时间:2016-04-20 09:05:14

标签: ios swift uistoryboard

我在故事板中有一个UIViewController,其中有一个名为" MyViewController" (嵌入UINavigationController作为入口点), 我试图使用instantiateViewControllerWithIdentifier从另一个类访问它,如:

MyAccessor.swift

func accessMyViewController(){
  let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
  let vc = storyboard.instantiateViewControllerWithIdentifier("MyViewController")
  print(vc.description)
}

MyViewController.swift

override func viewDidLoad() {
  print(self.description)
}

控制台

<MyViewController: 0x7ff6ab76f9c0>
<MyViewController: 0x7ff6ab557410>

我打印出不同的内存地址,

他们不应该是同一个人吗?

2 个答案:

答案 0 :(得分:2)

您的navigationController可能是故事板入口点

所以,如果它是真的,有两个实例..在你的应用程序启动期间创建的,另一个在你的代码中以编程方式调用。

viewDidLoad 不会仅通过实例化视图控制器来调用,有关详细信息,请参阅documentation,否则您已经看过三次打印..

enter image description here

如果您想立即查看您的情况,请尝试修改您的打印行:

<强> MyAccessor.swift

func accessMyViewController(){
    ...
    print("∙ \(NSStringFromClass(self.dynamicType)) - vc details : \(vc.description) ")
}

<强> MyViewController.swift

override func viewDidLoad() {
    ...
    print("∙ \(NSStringFromClass(self.dynamicType)) - self details : \(self.description) ")
}

答案 1 :(得分:1)

如此方法的documentation所述,它将始终创建一个新实例:

  

每次调用时,此方法都会创建指定视图控制器的新实例。

如果您需要视图控制器的相同实例,则需要将引用存储在其他位置(例如,创建第一个实例的视图控制器)。

第一个实例MyViewController可能是由故事板本身创建的,因为它是初始视图控制器。

<强>更新

再次查看代码和问题之后,我现在知道到底发生了什么。 如上所述,导航控制器是故事板的入口点。这意味着MyViewController的第一个实例是由故事板创建的,这导致viewDidLoad方法中的第一个打印。 第二个实例由 MyAccessor.swift 中的代码创建。同一文件内的打印通向第二个输出行。但是,永远不会加载第二个实例的视图,这会导致永远不会调用viewDidLoad。如果您在loadViewIfNeeded上调用vc,则会导致第三个输出行,该行将打印与 MyAccessor.swift中的print相同的内存地址