In my application, I have pushed from oneviewcontroller to anotherviewcontroller. In that page I have started a timer and updated UITableview for every 1 sec (using UITableview reloaddata).
I have start the timer in viewwillappear function and invalidate timer in viewwilldisappear.
But when timer is running, when I came back to my viewcontroller my application crashed rapidly.
Please help me? Thanks in advance...
My guess is when i push back to viewcontroller that time tablereloads in previous viewcontroller that time it make crashes. I am using try catch but nothing makes any difference. Can we stop tableview reloads when we are not in that page?
The main reason of your app crashing is that, when-ever u come back form anotherViewController to oneViewController, your table view got release in between your timer still alive which is trying to update tableView and when you accessing the release object then app will get crashed. So u need to before stop your timer properly and nil it if timer isValid.
I hope mine answer will help you.
You strongly need to send invalidate message to all you timers at dealloc method of your class
- (void)dealloc
{
if ([_someTimer isValid]) [_someTimer invalidate];
}
Related
I am trying to dealloc / destroy an NSTimer after a user clicks back, but the deinit{...} inside the uiviewcontroller never gets called.
Beware that a view controller going out of the screen does not mean that it will be deallocated afterwards. I would recommend moving the timer dealloc to viewDidDisappear, but obviously it depends what you are using that timer for as well.
I have one timer that will countdown the time to 0. timer stop fine when it reach to 0 and when clicking submit button but timer doesn't stop when go out the application and come back.
I tried to create the timer in viewWillAppear and invalidate it in viewWillDisappear but timer still running after coming back from background. How to stop timer when enter to background? Any sample?
Thanks
You can use NSNotificationCenter. Add observer for UIApplicationDidEnterBackgroundNotification and stop your timer in it. You won't have to create your timer in AppDelegate in this case.
You can use the :
- (void)applicationDidEnterBackground:(UIApplication *)application
method of appDelegate class to stop your time . But for that you have to declare the timer inside the appDelegate class. Also you have to persist the counter when you will go to background .
Then you can use the viewWillAppear:
method to restart the timer.
In my app, I have a UITableViewController which loads calculated data from my Core Data store. This can take quite some time and hangs the main thread, so to give the user visual feedback, I have installed the MBProgressHUD widget which will show a progress indicator (just the spinning wheel) while the calculation method runs in a separate thread.
This is fine, except that the user can still exit the UITableViewController if they think it's taking too long. Of course, this is a good thing, except that when the separate thread concludes its operation, it still tries to call its delegate (the UITableViewController) to hide the MBProgressHUD. This causes a crash because since the user already exited the UITableViewController, it has dealloc'd and release'd itself.
MBProgressHUD has the following code to try to stop this:
if(delegate != nil && [delegate conformsToProtocol:#protocol(MBProgressHUDDelegate)]) {
if([delegate respondsToSelector:#selector(hudWasHidden)]) {
[delegate performSelector:#selector(hudWasHidden)];
}
}
However, my app somehow seems to still be running this inner code ([delegate performSelector:#selector(hudWasHidden)]) even though the UITableViewController is totally gone--causing the app to crash.
Any suggestions? I am not running with NSZombiesEnabled.
From your UITableViewController viewWillDisappear, viewDidDisappear or dealloc method, set the MBProgressHUD.delegate = nil;
Once the user has exited the table controller, the delegate property of the hud points to a deallocated object (= a memory zone that could contain anything). That causes the crash when the computing thread ends and tries to send any message to the delegate.
In your table view controller dealloc, you must set the hud delegate to nil.
I have a weird problem invalidating NSTimer. As long as the user is on a particular screen, I need to constantly update it. I'm using NSTimer to accomplish it. I wrote the below piece of code in viewDidLoad method.
- (void)viewDidLoad {
self.pollServerForUpdates = [NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(fetchNewDataFromServer:)
userInfo:nil
repeats:YES];
}
Problem is when I try to invalidate the timer. As I want the app to stop polling the server when the user leaves the screen, I put the timer invalidation code in viewWillDisappear method.
-(void) viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:YES];
//NSLog(#"%d",[self.view retainCount]);
[self.pollServerForUpdates invalidate];
self.pollServerForUpdates = nil;
}
I use a navigation controller to go back and forth between my main view and the polling view. The app crashes if I move between my main view and polling view real fast. I enabled the NSZombie to see whats happening and this is what I get
*** -[CALayer retainCount]: message sent to deallocated instance 0x1c3be0
If I remove the timer invalidation my app works fine. But I want to stop the polling (timer) as soon as the user leaves the screen.
I believe this is happening because the timer is called a split second before the view is released, how do I avoid it? Do I need to change my design? Any help will be appreciated.
p.s: I can't use push notifications on this screen.
It may be that the bug is somewhere else, with some other class that is using your view without holding a reference to it. If you don't invalidate your timer than it will have a reference to your view forever, potentially extending its lifespan and masking memory management bugs elsewhere in your code.
Try breaking on exceptions, and see where the call to the zombie is coming from.
it happens only on the 3GS, 4 or 3G is OK.
seems like viewcontroller got called everytime camera dismissed.
any thoughts on that?
It's Iphone, the system calls viewdidunload my view of viewcontroller when I did a
[self presentModalViewController:picker1 animated:YES];
I don't want the system to dismiss my view. I did a [self.view retain] but that doesn't help.
viewDidLoad can be called multiple times. If the iPhone needs memory, it will release the view and then rebuild it the next time it has to show it. This is normal -- you cannot count on only a single call. You should get a viewDidUnload call before it's called again.