Question about NSTimer and retain

限于喜欢 提交于 2019-11-28 12:40:02

问题


This code works well

@property (nonatomic, retain) NSTimer *timer;
self.timer = [[NSTimer timerWithTimeInterval:kAdsAppearTimeInterval target:self selector:@selector(timerFired:) userInfo:nil repeats:NO] retain];

this code get CFRelease . But why? i use retain property

self.timer = [NSTimer timerWithTimeInterval:kAdsAppearTimeInterval target:self selector:@selector(timerFired:) userInfo:nil repeats:NO];

回答1:


Not a lot to go on... but:

@property (nonatomic, retain) NSTimer *timer;
self.timer = [[NSTimer timerWithTimeInterval:kAdsAppearTimeInterval target:self selector:@selector(timerFired:) userInfo:nil repeats:NO] retain];

That'll end up retaining the timer 3 times and self once.

  1. Timer +1 for -retain
  2. Timer +1 for scheduling it
  3. Timer +1 for the property assignment

  4. self +1 for being the target of the timer

The timer will be released once when fired (because it'll be unscheduled from the run loop). self will be released when the timer is invalidated or released (you shouldn't have to care).

So, you have two retain counts to account for. The call to retain in the code above is noise; don't bother as the property assignment will retain it.

That leaves the property's retain. The most obvious way is to release the timer in -dealloc.

However, unless you need to potentially invalidate the timer before it fires, there is no reason to have an instance variable referring to the timer at all. Even if you do have an iVar, there is no reason to retain the timer either as long as you set self.timer = nil in your timerFired: method (and set it to nil if you invalidate anywhere).




回答2:


For a non-repeating timer, if you need a reference to the instance variable, I would not recommend a retain property in its declaration to avoid confusion.

setting the instance variable (myTimer)

 myTimer = [NSTimer scheduledTimerWithTimeInterval:myTimerInterval
                                            target:self
                                          selector:@selector(myTimerFired:)
                                          userInfo:nil
                                           repeats:NO];

when the timer fires, you can mark the instance variable as nil since its released when the timer is fired

- (void) myTimerFired: (NSTimer *) theTimer{

            myTimer = nil;
        //etc
    }

This way if you have to reference your instance variable (for example to disable the timer when exiting a View controller)

 -(void) onBack {
             if(myTimer){
                 [myTimer invalidate];
                 myTimer = nil;
              }
    }


来源:https://stackoverflow.com/questions/4914906/question-about-nstimer-and-retain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!