Mel*_*emi 20 iphone cocoa-touch uiviewcontroller viewdidload
任何人都知道为什么这个根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
Run Code Online (Sandbox Code Playgroud)
第二次:
#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
Run Code Online (Sandbox Code Playgroud)
har*_*lee 16
我的应用程序首次启动时遇到了同样的问题.我发现在我的MainWindow.xib文件中,我将我的App Delegate的viewController插座和我的Window的rootViewController插座设置为我的根视图控制器.在Xcode中构建基于视图的项目文件时,您的App Delegate didFinishLaunchingWithOptions将预先填充:
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
Run Code Online (Sandbox Code Playgroud)
我相信self.viewController在didFinishLaunchingWithOptions调用之前,ivar是从MainWindow.xib实例化的.然后上面预先填充的代码设置Window的rootViewController.因此,如果您rootViewController在MainWindow.xib文件中指定Window 的出口,则实际上将创建两次根视图控制器并将其添加为Window的根视图控制器两次.
小智 8
我做了一些调试,这是我发现的有关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
Run Code Online (Sandbox Code Playgroud)
在loadView方法期间,initWithCoder:调用它并viewController创建一个新副本.这是传递给一些方法(如viewDidLoad)的内容.稍后在dealloc调用中销毁副本.好消息是,在此副本中,未配置保留的插座,因此您可以将其用作测试,以了解是否应初始化变量,调用其他方法,最重要的是,如果您应在dealloc期间释放和销毁对象.
关键点:真实viewController将IBOutlet配置其保留属性.如果您处于被多次调用的重写方法中,只需选中一个保留的IBOutlet属性即可NULL.如果是NULL,则立即返回.
任何人都知道为什么会这样发生?
这样的副作用:你不能awakeFromNib可靠使用.
诡异的。我还没有见过这种特殊情况,但一般来说,您应该假设 viewDidLoad 可以被多次调用。每当加载引用该控制器的 nib 文件时,都会调用它。
对于一个只有一个笔尖的简单应用程序来说,这种情况不应该发生。但在可以加载和卸载视图控制器的更复杂的应用程序中,这种情况经常发生。