关于NSTimer和retain的问题

发布于 2024-10-16 03:33:46 字数 437 浏览 6 评论 0原文

这段代码运行良好,

@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];

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];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听你说爱我 2024-10-23 03:33:46

没什么可继续的...但是:

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

这最终会保留计时器 3 次和 self 一次。

  1. 用于 -retain 的 Timer +1
  2. 用于调度它的 Timer +1
  3. 用于属性分配的 Timer +1

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

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

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

这就留下了财产的保留。最明显的方法是在 -dealloc 中释放计时器。

但是,除非您需要在计时器触发之前使计时器无效,否则根本没有理由拥有引用计时器的实例变量。即使您确实有 iVar,也没有理由保留计时器只要您在 timerFired: 方法中设置 self.timer = nil(并将其设置为如果您在任何地方无效,则为零)。

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).

薯片软お妹 2024-10-23 03:33:46

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

设置实例变量(myTimer)

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

当计时器触发时

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

            myTimer = nil;
        //etc
    }

,您可以将实例变量标记为 nil,因为它在计时器触发时被释放。这样,如果您必须引用实例变量(例如,在退出视图控制器时禁用计时器) )

 -(void) onBack {
             if(myTimer){
                 [myTimer invalidate];
                 myTimer = 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 = [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;
              }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文