NSTimer中的迴圈引用

2021-07-15 07:01:58 字數 2387 閱讀 2690

- (void)viewdidload 

- (void)p_dosomething

- (void)p_stopdosomething

- (void)dealloc

上面的**主要是利用定時器重複執行p_dosomething方法,在合適的時候呼叫p_stopdosomething方法使定時器失效.

scheduledtimerwithtimeinterval: target: selector: userinfo: repeats:

方法的最後乙個引數為yes時,nstimer會保留目標物件,等到自身失效才釋放.執行完任務後,一次性的定時器會自動失效;重複性的定時器,需要主動呼叫invalidate方法才會失效.

建立定時器時,當前控制器(建立定時器的那個控制器,為了描述方便,簡稱當前控制器)引用而定時器了(為什麼因引用定時器?後續要用到這個定時器物件),在給定時器新增任務時,定時器保留了self(當前控制器).這裡就出現了迴圈引用.

如果能在合適的時候打破迴圈引用,就不會有問題了.此時有兩種選擇:

1.控制器不再引用定時器

2.定時器不再保留當前控制器

第一種是不可行的,那麼就只有第二種方法了.也就是合適的時候呼叫p_stopdosomething方法.然而,合適的時機很難找到.假如這是乙個驗證碼倒計時程式,你可以在倒計時結束時呼叫p_stopdosomething方法.但是你不能確定使用者一定會等倒計時結束才返回到上一級頁面.或許你想在dealloc方法中使定時器失效,那你就太天真了.此時定時器還保留著當前控制器,此方法是不可能呼叫的,因此會出現記憶體洩漏.或許在倒計時程式中,你可以重寫返回方法,先呼叫p_stopdosomething再返回,但這不是乙個好主意.

該問題出現的根本原因就是無法確保一定會呼叫p_stopdosomething方法

#import @inte***ce nstimer (whunretain)

+ (nstimer *)wh_scheduledtimerwithtimeinterval:(nstimeinterval)inerval

block:(void(^)())block

repeats:(bool)repeats;

@end

#import "nstimer+whunretain.h"

@implementation nstimer (whunretain)

+ (nstimer *)wh_scheduledtimerwithtimeinterval:(nstimeinterval)inerval block:(void (^)())block repeats:(bool)repeats

+ (void)wh_blcokinvoke:(nstimer *)timer

}@end

#import "viewcontroller.h"

#import "nstimer+whunretain.h"

//定義了乙個__weak的self_weak_變數

#define weakifyself  \

__weak __typeof(&*self)weakself = self;

//局域定義了乙個__strong的self指標指向self_weak

#define strongifyself \

__strong __typeof(&*weakself)self = weakself;

@inte***ce viewcontroller ()

@property (nonatomic, strong)nstimer *timer;

@end

@implementation viewcontroller

- (void)viewdidload repeats:yes];

}- (void)startdosomethings

- (void)stopdosomethings

weakifyself巨集定義了乙個弱引用的weakself,strongifyself巨集又根據weakself定義了乙個強引用的self.這樣在block內使用self和其他地方一樣.這裡的self和block外的self指向一樣,但是不同的變數.

NSTimer的迴圈引用問題

timer nstimer scheduledtimerwithtimeinterval 1.0 target self selector selector countdown userinfo nil repeats yes property nonatomic,strong nstimer ti...

iOS中解決NSTimer迴圈引用的三種方式

今天有個人來公司面試,問了他平時在使用timer定時器時怎麼解決迴圈引用的問題。然後就得到了這樣乙個答案 weak typeof self weakself self self.timer nstimer scheduledtimerwithtimeinterval 1.0 target weaks...

iOS中迴圈引用的解除

一 為什麼造成了迴圈引用?首先 對於網路工具類 finishedblock裡面 的乙個屬性是 copy的 那麼 networktools 會對網路工具 finishedblock進行乙個強引用 左邊的控制器viewcontroller裡面 viewcontroller 對 networktools物...