viewDidLoad getting called twice on rootViewContro

2020-01-27 03:38发布

Anyone know why this root View Controller's viewDidLoad is being called twice at launch? It's driving me nuts!

here's the stack trace from first time through 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

and the second time:

#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

11条回答
混吃等死
2楼-- · 2020-01-27 04:01

Just to add to this, if you are using a system function, such as TouchID, then applicationWillResignActive in your AppDelegate will get invoked and if you are say, resetting controllers to a Secure Root Controller then you get reinvoked, and performSegueWithIdentifier(self.MAIN_SEGUE ,sender: self) will not fire!

查看更多
Fickle 薄情
3楼-- · 2020-01-27 04:02

Weird. I haven't seen this particular case, but in general, you ought to assume that viewDidLoad can be called multiple times. It'll get called whenever a nib file that references that controller gets loaded.

For a simple app with only one nib, that shouldn't happen. But in a more-complex app that can load and unload view controllers, this happens all the time.

查看更多
兄弟一词,经得起流年.
4楼-- · 2020-01-27 04:02

What if your code did access the view property when it is not loaded yet, the view controller will create just empty view and it could trigger view did load accidentally.

Most common error is accessing view property during initialization. May be some property accessor(setter) that is invoked by xib should access view property accidentally.

What if some property is annotated with IBInspectable you should have to check isViewLoaded before apply some value to view.


-(void) setSomeProperty:(UIColor*) someColor
{
  _someColor = someColor;
  if(self.isViewLoaded) {
    // self.view causes view creation and invokes 'viewDidLoad' then the view is not ready yet.
    self.view.backgroundColor = someColor;
  }
}

-(void) viewDidLoad
{
  [super viewDidLoad]
  if(_someColor){
    self.view.backgroundColor = _someColor;
  }
}

查看更多
劫难
5楼-- · 2020-01-27 04:03

I had this problem but was able to fix it.

Solution:

Rename the view controller class that is loading twice.

Details:

Rename it and make the new name something entirely new. Renaming the file doesn't stop the load-twice issue. Creating a new project (as suggested by others) might be overkill, at least try the simpler solutions first! Rename the class of the destination VC.

Hint: If renaming the class fixes your issue, you then obviously have to update all your references to that class. You can speed this up by using Command+Shift+F for project-wide find.

查看更多
狗以群分
6楼-- · 2020-01-27 04:04

This happened to me when I merged a project from the storyboard to the old way using xibs for constructing views. The main reason for switching back was the fact I couldn't properly put up a modal view properly. The way I usually do it is by having a delegate method from a UIButton construct an instance of a certain viewcontroller, set some of its properties (the most import one being the delegate so i can properly dismiss the modal view controller again) and then present it in a modal way. In the new storyboard way, this is supposedly done with a segue. Customizing the transition is only doable by making a custom class that extends the UIStoryboardSegue class. I find this way too much hassle compared to the simple way it used to be so I merged back.

How did this cause me to have a viewcontroller load twice? When transferring the code from the storyboard project to the xib project, I made a couple of xibs (one for each ViewController) and copied the viewcontroller object from the storyboard. This led to a xib with in it not a viw, but a viewcontroller; meaning i had put a viewcontroller in a viewcontroller (since the file's owner is also an instance of the viewcontroller). I don't think in your case that you had this problem but I hope it maybe helps someone some day.

To fix this move the view from the view controller out of the view controller and to the root level of the objects section. Both the view controller and it's navigation item should be deleted. Build and run and you should see only one allocation for the view controller. This is the file owner.

查看更多
一纸荒年 Trace。
7楼-- · 2020-01-27 04:05

In my case, I didn't notice that I have actually assigned the rootViewController twice in:

application:didFinishLaunchingWithOptions: and applicationDidBecomeActive:

查看更多
登录 后发表回答