关于NSTimer的问题并保留

时间:2011-02-06 17:28:29

标签: iphone memory nstimer retain

此代码效果很好

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

此代码获得CFRelease。但为什么?我使用保留属性

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

2 个答案:

答案 0 :(得分:10)

不是很多......但是:

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

这将最终保留计时器3次并自我保护一次。

  1. 计时器+1 for -retain
  2. 计划+1用于安排它
  3. 属性作业的计时器+1

  4. self +1作为计时器的目标

  5. 定时器在被触发时将释放一次(因为它将从运行循环中取消预定)。当计时器失效或被释放时,self将被释放(你不必关心)。

    因此,您需要考虑两个保留计数。上面代码中对retain的调用是噪音;不要打扰,因为财产分配会保留它。

    这使得该物业得以保留。最明显的方法是在-dealloc中释放计时器。

    但是,除非您在计时器触发之前需要使计时器失效,否则根本没有理由让一个实例变量引用计时器。即使你有一个iVar,只要你在timerFired:方法中设置self.timer = nil,就没有理由保留计时器(如果你设置为nil,则设置为nil无处不在)。

答案 1 :(得分:0)

对于非重复计时器,如果需要对实例变量的引用,我不建议在其声明中使用retain属性以避免混淆。

设置实例变量(myTimer)

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

当计时器触发时,你可以将实例变量标记为nil,因为它在计时器被触发时被释放

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

            myTimer = nil;
        //etc
    }

这样,如果你必须引用你的实例变量(例如在退出View控制器时禁用定时器)

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