开发者

Dealloc called twice and crash at [super dealloc]

---- question solved by myself, info updated in my comment ----

I have a view controller which has a periodic NSTimer. I call invalidate of the timer When I remove the view controller:

- (void)dealloc
{
    NSLog(@"dealloc called");
    if ([myTimer isValid]) {
        [myTimer invalidate];
    }
    [super dealloc];
} 

I discovered an unexpected behavior that the [myTimer in开发者_运维技巧validate] will immediately call my view controller's dealloc. That's why I put the isValid check to avoid crash. But the [super dealloc] will be called twice and crash the app.

Thus, I have two questions:

  1. What's the proper way to invalidate a timer?

  2. Why is the timer's invalidate method call the view controller's dealloc method?

Thanks

Leo


As described at CocoaDev: NSTimer:

Here are a couple of rules that might help you with NSTimer:

A timer retains the target and userInfo objects.

A timer is automatically retained by the run loop when scheduling it.

If a timer is not set to repeat, it will automatically invalidate itself upon firing.

A timer is released from the run loop when calling invalidate.

A timer releases the target and userInfo objects when calling invalidate.

In other words, if you release a repeating timer without invalidating it, it will continue to repeate because the run loop is retaining it. However, if you don't want to stop the timer before the application quits, or if the timer is non-repeating, you can release it after scheduling it without calling invalidate.


That sounds like some odd behaviour. Are there any other objects holding on to a reference to your view controller?

If not, there is a possibility that once the timer is removed & released from the run loop the view controller has nothing referencing it anymore (and so is deallocated).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜