使用 instantiateViewControllerWithIdentifier 访问相同的视图控制器
Access the identical view controller using instantiateViewControllerWithIdentifier
我在故事板中有一个 UIViewController
,故事板 ID 称为 "MyViewController"(嵌入 UINavigationController
作为入口点),
我正在尝试使用 instantiateViewControllerWithIdentifier
从另一个 class 访问它,例如:
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>
我打印出不同的内存地址,
他们不应该是同一个人吗?
如该方法的 documentation 中所述,它将始终创建一个新实例:
This method creates a new instance of the specified view controller each time you call it.
如果您需要相同的视图控制器实例,则需要将引用存储在其他地方(例如创建第一个实例的视图控制器)。
第一个实例 MyViewController
可能是由故事板本身创建的,因为它是初始视图控制器。
更新:
看了代码再问,终于知道是怎么回事了。
如前所述,导航控制器是故事板的入口点。这意味着 MyViewController
的第一个实例是由故事板创建的,它导致 viewDidLoad
方法中的第一个打印。
第二个实例由 MyAccessor.swift 中的代码创建。同一文件内的打印导致第二个输出行。但是,永远不会加载第二个实例的视图,这会导致永远不会调用 viewDidLoad
。如果你在 vc
上调用 loadViewIfNeeded
它将导致第三行输出,它将打印与 MyAccessor.swift 中的 print
相同的内存地址.
可能您的导航控制器是故事板入口点。
所以,如果这是真的,那么有两个实例..一个在您的应用程序启动期间创建,另一个从您的代码中以编程方式调用。
P.S.: viewDidLoad不会仅仅通过实例化一个view controller来调用,详见documentation..,否则你已经看到了三个打印..
如果您想立即查看您的情况,请尝试修改您的打印行:
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) ")
}
我在故事板中有一个 UIViewController
,故事板 ID 称为 "MyViewController"(嵌入 UINavigationController
作为入口点),
我正在尝试使用 instantiateViewControllerWithIdentifier
从另一个 class 访问它,例如:
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>
我打印出不同的内存地址,
他们不应该是同一个人吗?
如该方法的 documentation 中所述,它将始终创建一个新实例:
This method creates a new instance of the specified view controller each time you call it.
如果您需要相同的视图控制器实例,则需要将引用存储在其他地方(例如创建第一个实例的视图控制器)。
第一个实例 MyViewController
可能是由故事板本身创建的,因为它是初始视图控制器。
更新:
看了代码再问,终于知道是怎么回事了。
如前所述,导航控制器是故事板的入口点。这意味着 MyViewController
的第一个实例是由故事板创建的,它导致 viewDidLoad
方法中的第一个打印。
第二个实例由 MyAccessor.swift 中的代码创建。同一文件内的打印导致第二个输出行。但是,永远不会加载第二个实例的视图,这会导致永远不会调用 viewDidLoad
。如果你在 vc
上调用 loadViewIfNeeded
它将导致第三行输出,它将打印与 MyAccessor.swift 中的 print
相同的内存地址.
可能您的导航控制器是故事板入口点。
所以,如果这是真的,那么有两个实例..一个在您的应用程序启动期间创建,另一个从您的代码中以编程方式调用。
P.S.: viewDidLoad不会仅仅通过实例化一个view controller来调用,详见documentation..,否则你已经看到了三个打印..
如果您想立即查看您的情况,请尝试修改您的打印行:
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) ")
}