nstimer循环引用_警惕使用NSTimer时的循环引用
使用NSTimer可能會碰到循環引用的問題。特別是當類具有NSTimer類型的成員變量,并且需要反復執行計時任務時。例如
_timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(startCounting) userInfo:nil
repeats:YES];
類有一個成員變量_timer,給_timer設置的target為這個類本身。這樣類保留_timer,_timer又保留了這個類,就會出現循環引用的問題,最后導致類無法正確釋放。
解決這個問題的方式也很簡單,當類的使用者能夠確定不需要使用這個計時器時,就調用
[_timer invalidate];
_timer = nil;
這樣就打破了保留環,類也可以正確釋放。但是,這種依賴于開發者手動調用方法,才能讓內存正確釋放的方式不是一個非常好的處理方式。所以需要另外一種解決方案。如下所示:
@interface NSTimer (JQUsingBlock)
+ (NSTimer *)jq_scheduledTimerWithTimeInterval:(NSTimeInterval)ti
block:(void(^)())block
repeats:(BOOL)repeats;
@end
@implementation NSTimer (JQUsingBlock)
+ (NSTimer *)jq_scheduledTimerWithTimeInterval:(NSTimeInterval)ti
block:(void(^)())block
repeats:(BOOL)repeats{
return [self scheduledTimerWithTimeInterval:ti
target:self
selector:@selector(jq_blockInvoke:)
userInfo:[block copy]
repeats:repeats];
}
+ (void)jq_blockInvoke:(NSTimer *)timer{
void(^block)() = timer.userInfo;
if (block) {
block();
}
}
@end
定義一個NSTimer的類別,在類別中定義一個類方法。類方法有一個類型為塊的參數(定義的塊位于棧上,為了防止塊被釋放,需要調用copy方法,將塊移到堆上)。使用這個類別的方式如下:
__weak ViewController *weakSelf = self;
_timer = [NSTimer jq_scheduledTimerWithTimeInterval:5.0
block:^{
__strong ViewController *strongSelf = weakSelf;
[strongSelf startCounting];
}
repeats:YES];
使用這種方案就可以防止NSTimer對類的保留,從而打破了循環引用的產生。__strong ViewController *strongSelf = weakSelf主要是為了防止執行塊的代碼時,類被釋放了。在類的dealloc方法中,記得調用[_timer invalidate]。
總結
以上是生活随笔為你收集整理的nstimer循环引用_警惕使用NSTimer时的循环引用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java模拟器百度_Java模拟实现百度
- 下一篇: 微软 rms服务器端,微软RMS服务器部