有人知道为什么这个根View Controller's
viewDidLoad
在启动时会被调用两次吗?快把我逼疯了!
下面是从第一次到viewDidLoad
的堆栈跟踪
#0 0x0000276a in -[RootViewController viewDidLoad] at RootViewController.m:71
#1 0x3097548f in -[UIViewController view]
#2 0x00002734 in -[RootViewController initWithCoder:] at RootViewController.m:39
#3 0x30ab5ce4 in -[UIClassSwapper initWithCoder:]
#4 0x30514636 in _decodeObjectBinary
#5 0x30514035 in _decodeObject
#6 0x30ab5a1d in -[UIRuntimeConnection initWithCoder:]
#7 0x30514636 in _decodeObjectBinary
#8 0x30515f27 in -[NSKeyedUnarchiver _decodeArrayOfObjectsForKey:]
#9 0x305163b0 in -[NSArray(NSArray) initWithCoder:]
#10 0x30514636 in _decodeObjectBinary
#11 0x30514035 in _decodeObject
#12 0x30ab4dde in -[UINib instantiateWithOptions:owner:loadingResourcesFromBundle:]
#13 0x30ab6eb3 in -[NSBundle(NSBundleAdditions) loadNibNamed:owner:options:]
#14 0x308f85f1 in -[UIApplication _loadMainNibFile]
#15 0x30901a15 in -[UIApplication _runWithURL:sourceBundleID:]
#16 0x308fef33 in -[UIApplication handleEvent:withNewEvent:]
#17 0x308fad82 in -[UIApplication sendEvent:]
#18 0x309013e1 in _UIApplicationHandleEvent
#19 0x32046375 in PurpleEventCallback
#20 0x30245560 in CFRunLoopRunSpecific
#21 0x30244628 in CFRunLoopRunInMode
#22 0x308f930d in -[UIApplication _run]
#23 0x309021ee in UIApplicationMain
#24 0x000022e4 in main at main.m:14
第二次:
#0 0x0000276a in -[RootViewController viewDidLoad] at RootViewController.m:71
#1 0x30ab50cd in -[UINib instantiateWithOptions:owner:loadingResourcesFromBundle:]
#2 0x30ab6eb3 in -[NSBundle(NSBundleAdditions) loadNibNamed:owner:options:]
#3 0x308f85f1 in -[UIApplication _loadMainNibFile]
#4 0x30901a15 in -[UIApplication _runWithURL:sourceBundleID:]
#5 0x308fef33 in -[UIApplication handleEvent:withNewEvent:]
#6 0x308fad82 in -[UIApplication sendEvent:]
#7 0x309013e1 in _UIApplicationHandleEvent
#8 0x32046375 in PurpleEventCallback
#9 0x30245560 in CFRunLoopRunSpecific
#10 0x30244628 in CFRunLoopRunInMode
#11 0x308f930d in -[UIApplication _run]
#12 0x309021ee in UIApplicationMain
#13 0x000022e4 in main at main.m:14
发布于 2009-07-03 23:41:03
真奇怪。我还没有见过这种特殊的情况,但一般来说,您应该假设viewDidLoad可以被多次调用。每当加载引用该控制器的nib文件时,它都会被调用。
对于一个只有一个笔尖的简单应用来说,这是不应该发生的。但在可以加载和卸载视图控制器的更复杂的应用程序中,这种情况时有发生。
发布于 2011-09-02 03:47:32
当我的应用程序第一次启动时,我也遇到了同样的问题。我发现,在我的MainWindow.xib文件中,我将App Delegate的viewController
outlet和Window的rootViewController
outlet都设置为根视图控制器。当您在Xcode中构建基于视图的项目文件时,您的应用程序代表的didFinishLaunchingWithOptions
将预先填充以下内容:
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
我相信self.viewController
ivar是在didFinishLaunchingWithOptions
被调用之前从MainWindow.xib实例化的。然后,上面预先填充的代码设置窗口的rootViewController
。因此,如果您在MainWindow.xib文件中为窗口指定了rootViewController
插座,那么您的根视图控制器实际上将被创建两次,并被添加为窗口的根视图控制器两次。
发布于 2010-02-06 01:44:53
我做了一些调试,下面是我发现的有关ViewController
加载顺序的内容:
initWithNibName:bundle: self = <original instance>, retainedOutlet = 0x0
loadView >>> self = <original instance>, retainedOutlet = 0x0
initWithCoder: self = <coder instance>, retainedOutlet = 0x0
initWithCoder: self = <coder instance>, retainedOutlet = 0x0
setView: self = <original instance>, retainedOutlet = 0x0
setRetainedOutlet: self = <original instance>, retainedOutlet = 0x1613c40
viewDidLoad self = <coder instance>, retainedOutlet = 0x0
awakeFromNib self = <coder instance>, retainedOutlet = 0x0
loadView <<<
viewDidLoad self = <original instance>, retainedOutlet = 0x1613c40
viewWillAppear: self = <original instance>, retainedOutlet = 0x1613c40
dealloc self = <coder instance>, retainedOutlet = 0x0
viewDidAppear: self = <original instance>, retainedOutlet = 0x1613c40
在loadView方法期间,将调用initWithCoder:
并创建viewController
的新副本。这就是传递到少数方法(如viewDidLoad
)中的内容。副本稍后会在dealloc调用中销毁。好消息是,在这个副本中,保留的出口没有配置,所以你可以用它来测试你是否应该初始化变量,调用其他方法,最重要的是,你是否应该在dealloc期间释放和销毁对象。
要点:真正的viewController
将配置其保留的IBOutlet
属性。如果您在一个被多次调用的被覆盖的方法中,只需检查NULL
的一个保留的IBOutlet
属性。如果它们是NULL
,则立即返回。
有谁知道为什么会这样吗?
这样做的副作用:你不能可靠地使用awakeFromNib
。
https://stackoverflow.com/questions/1081131
复制相似问题