简体   繁体   English

有关NSTimer和保留的问题

[英]Question about NSTimer and retain

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 . 此代码获取CFRelease。 But why? 但为什么? i use retain property 我使用保留财产

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

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. 最终将计时器保留3次,自我保留一次。

  1. Timer +1 for -retain 计时器+1用于-retain
  2. Timer +1 for scheduling it 计时器+1进行安排
  3. Timer +1 for the property assignment 计时器+1用于属性分配

  4. self +1 for being the target of the timer self +1作为计时器的目标

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). 计时器无效或释放时, self将被释放(您不必在意)。

So, you have two retain counts to account for. 因此,您需要考虑两个保留计数。 The call to retain in the code above is noise; retain在上面代码中的要求是噪音。 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. 最明显的方法是在-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). 即使您确实拥有iVar,也没有理由保留计时器,只要您在timerFired:方法中设置self.timer = nil (如果在任何地方使它无效,则将其设置为nil)即可。

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)

 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 当计时器启动时,您可以将实例变量标记为nil,因为自从计时器启动时释放该实例变量

- (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) 这样,如果您必须引用实例变量(例如,在退出View控制器时禁用计时器)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM