差異

2017-07-06 101 views
5

因爲我們知道,我們需要使用一個弱引用塊內部打破保留週期,就像這樣:差異

__weak id weakSelf = self; 
[self doSomethingWithABlock:^() { 
    [weakSelf doAnotherThing]; 
}] 

但是弱引用無法打破保留週期由NSTimer引起。

__weak id weakSelf = self; 
timer = [NSTimer scheduledTimerWithTimeInterval:30.0f 
             target:weakSelf 
             selector:@selector(tick) 
             userInfo:nil 
             repeats:YES]; // No luck 

有什麼區別?定時器如何仍能保持目標?

+0

BTW,定義'weakSelf'時我們通常使用'typeof(self)'而不是'id'。 – Rob

回答

6

基於選擇器的NSTimer技術的整個問題在於它對傳遞給它的對象建立了強有力的參考。因此,您用來持有對您傳遞給scheduledTimerWithTimeInterval的目標的引用的變量本身是強還是弱,是否無關緊要。假設到安排基於選擇器的計劃計時器時,target參考不是nilNSTimer將建立自己的強參考。調用代碼中引用的「弱」與「強」性質僅指示ARC將在調用者的代碼中放置其自己的內存管理調用,但target只是一個簡單的指針,並且這些弱信息和強信息都沒有傳送到NSTimer。基於選擇器的NSTimer將建立自己的強參考,直到計時器爲invalidated才能解決問題。

這就是爲什麼當我們想要使通過基於選擇器的方法構建的定時器無效時,我們必須在viewDidDisappear之類,而不是dealloc

注意,scheduledTimerWithTimeInterval現在有iOS的10基於塊的變化及更高版本,讓您可以享受塊的弱引用模式,如果你沒有支持早期IOS版本:

typeof(self) __weak weakSelf = self; 
[NSTimer scheduledTimerWithTimeInterval:30 repeats:true block:^(NSTimer * _Nonnull timer) { 
    // use weakSelf here 
}];