After upgrading my SDK version I noticed that cellForRowAtIndexPath is always called prior to viewWillAppear. Previously the order of execution was opposite: viewWillAppear would always be called prior to cellForRowAtIndexPath. Because my application logic often used viewWillAppear to initialize objects that are subsequently used in cellForRowAtIndexPath, the application is often crashing.
I tried searching for an official expiation regarding this change with no success. I can likely move my initialization code to viewDidLoad, but wanted to see if there are better solutions or more information about this change in behavior.
You can just add the line
[self.tableView reloadData];
at the end of viewWillAppear and your problem will be fix
It is not "cellForRowAtIndexPath called before viewWillAppear", it is [super viewWillAppear:animated] will call UITableView's delegate.
I made the same mistake and it took me a lot of time to find it.
Related
Does [self viewDidAppear:YES]; in the viewDidLoad section of code ensure that the viewDidAppear section of code will run?
Based on feedback from a small subset of our users, it appears for whatever reason that the code I have written in the viewDidAppear section of the main menu's view is not running for them - but it works perfectly well for the majority of users and in all my testing. I'm hoping that by adding [self viewDidAppear:YES]; this will fix the issue for those devices that for some reason were not calling viewDidAppear...
What do you guys think?
I think that's a horrible idea, personally. I think you're better off finding out WHY viewDidAppear didn't execute for that subset of users. You may only be treating a symptom of a greater problem by just 'fixing' what appears to be wrong.
ViewDidAppear may not be getting called if its on a view controller that is nested in another view controller and running on an older OS. Before iOS 5, delegate commands did not always get forwarded to child controllers.
You should never call delegate methods directly.
Is there any other reason (than calling "reloadData") why numberOfSectionsInTableView is called twice? I did debugging and found, that it's get called twice during initial startup when no custom reloadData statements are called.
I have created the table with IB but does that might cause a problem?
Have a look at the call stack. you can see that this method is being called from two different scenarios.
Probably your tableView object may instantiate twice. Once i have encountered the same problem due to this.
i am experiencing a strange problem where the Method "ViewDidLoad" runs before the AppDelegate's didFinishLaunchingWithOptions gets executed!
Cause I only check if a database exists in "didFinishLaunchingWithOptions" my app crashes if the database isnt there. after poking around for a couple of hours I am tired of doing so and call for HEEEEELP!
If you please could be so kind and point me into the right direction what's likely to be wrong with my project. I cant figure it out (aaarggh!)
Thank you!
Best regards
Tom
viewDidLoad may run on ViewControllers loaded from NIBs as these are loaded before the call to didFinishLaunchingWithOptions:
I had the same issue and after looking in the code in more detail, I have found out that inside awakeFromNib of a xViewController, i am initing another yViewController. So the viewDidLoad of yViewController runs before didFinishLaunchingWithOptions:.
Basically, the initial VC's awakeFromNib is called before didFinishLaunchingWithOptions:. You might have something similar of a setup. Look into that.
If your database files do not load fast enough; override your AppDelegate's init():
override init() {
if filesExistBool == false {
addDBFiles()
}
}
I don't believe you.
In application:didFinishLaunchingWithOptions: you decide what views to load. The app will not randomly load views without you telling it to do so. Did you put a breakpoint first in viewDidLoad and one first in application:didFinishLaunchingWithOptions: or do you just assume that application:didFinishLaunchingWithOptions: didn't get executed because it's not working.
This is driving me nuts. I am using three20's TTTableViewController and when I get a memory warning, the screen goes white. Now, after reading on the three20 google group is seems that the tableView got released. But, I cannot for the life of me figure out a check to see if that is the case, then create it again.
I was using the following because I thought it would fix the issue, but it seems that it doesn't satisfy the if statement:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// If we don't have a datasource we need to reset it
if (!self.dataSource) {
// Create datasource again
}
}//end
Does anyone know what to do when this happens? The google group has been no help.
Are you subclassing TTTableViewController? I haven't used it before, but assuming it's just like UITableViewController...
How does your "viewDidUnload" look like? Are you releasing the tableview here? If so, you need to create tableview in viewDidLoad to match it.
No need to check if dataSource is available in viewDidAppear, because if you read View programming guide, it explains that memory warning will call "viewDidUnload" to give you a chance to clean up data that are created in "viewDidLoad".
i had the same issue and it drove me crazy as well.
Nobody mentions it in the three20 docs, but you shouldn't use UIViewController's initWithNibName function to add subviews. If you do, a memory warning will release these subviews.
Try to move your code from initWithNibName function to viewDidLoad function. I have noticed that some code need to be kept in the initWithNibName, such as navigation styles. However, any subviews added to the controller's view should be in the viewDidLoad function.
In general you should be careful to set up views in viewDidLoad rather than the class constructor. For instance, you should set up your launcher view in viewDidLoad rather than the constructor of your launcher view controller, otherwise your launcher will become empty after a memory warning.
In the case of TTTableViewController however this does not (usually) apply because you don't set up the table view manually. I had the same problem you had, and eventually tracked it down: I had redefined viewWillDisappear: and forgot to call [super viewWillDisappear:animated]. This meant that some of the flags that the Three20 controller maintains about the state of the view were not updated correctly.
I also found that it was beneficial to redefine didReceiveMemoryWarning to call [self setEditing:NO] before calling super; I found that the state of the table view got confused otherwise (this is not relevant if you don't use edit mode for your table).
Finally, there is a bug in Three20 which means that tables in loading/empty/error mode will not be restored properly; see a discussion in the blog post by TwoCentStudios and a proposed fix on github.
I've implemented a View Controller, and I'm trying to do some very basic initialization in initWithNibFile...which I understand to be the designated initializer for View Controller objects.
I've tried to put breakpoints on the code, and have put very simple NSLog statements into it as well. Regardless...I'm not seeing it be executed (and the object i'm attempting to alloc/init inside the function is also not being allocated - so I'm about 99% sure I'm not hitting the code.
Is there something I need to do elsewhere to cause this method to be invoked?
I'm getting a clean build, no warnings or errors. And the app successfully loads up the View, and I can invoke a ButtonClick method I've coded and connected to this same View Controller.
Any suggestions would be appreciated.
TC
I ended up moving my allocation logic to viewDidLoad, and that works fine.
Not sure why the initWithNibFile was not working...but I'll take the small victory !!!
Thanks for offering to look at the code bpapa.
You probably need initWithCoder: It's what the SDK uses to read from nib files during startup.
initWithNibFile: is almost never called by the system. Usually you call this manually. The documentation is quite misleading on this point.
In any case, be careful doing too much initialization in the initWithXXXX methods. The view's targets and actions aren't likely to be set up and connected yet. viewDidLoad is almost always the right place to do viewController setup anyways.