當我執行此代碼:的NSTimer內存管理
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];
,我需要它爲零或釋放它,OT不管內存管理?
我使用ARC
當我執行此代碼:的NSTimer內存管理
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];
,我需要它爲零或釋放它,OT不管內存管理?
我使用ARC
是的,NSTimer
將保持對target
的強烈參考,這會導致(特別是在重複定時器中)強參考週期(也稱爲保留週期)。在你的例子中,雖然定時器不重複,但延遲只有0.5,所以最壞的情況下,你將有一個強大的參考週期,它會在0.5秒內自動解決。
但一個未解決的強基準週期的一個常見的例子是將有一個UIViewController
與反覆進行NSTimer
屬性,但由於NSTimer
具有很強的參考UIViewController
,控制器將最終被保留。
所以,如果你保留NSTimer
作爲一個實例變量,那麼,是的,你應該invalidate
它,以解決強參考週期。如果您只是調用scheduledTimerWithTimeInterval
,但不將其保存到實例變量(如您可能從您的示例中推斷的那樣),那麼當NSTimer
完成時,您的強參考週期將得到解決。
而且,順便說一下,如果你正在處理重複NSTimers
,不要試圖invalidate
他們在NSTimer
所有者的dealloc
因爲dealloc
顯然不會被調用,直到有力的參考週期的解決。例如,在UIViewController
的情況下,您可以在viewDidDisappear
中執行此操作。
順便說一下,Advanced Memory Management Programming Guide解釋了什麼是強參考週期。顯然,這是在他們正在描述正確使用弱引用的部分中,這在這裏是不適用的(因爲您無法控制NSTimer
使用強引用的目標),但它確實解釋了這些概念很好的參考週期。
如果你不想讓你的NSTimer
保持強引用self
,在10.12的MacOS和iOS 10或更高版本,可以使用塊再現,然後使用weakSelf
模式:
typeof(self) __weak weakSelf = self;
[NSTimer scheduledTimerWithTimeInterval:0.5 repeats:false block:^(NSTimer * _Nonnull timer) {
[weakSelf showButtons];
}];
順便說一下,我注意到你打電話給showButtons
。如果你想只顯示在您的視圖中的某些控件,您可以消除使用NSTimer
完全的和做的是這樣的:
self.button1.alpha = 0.0;
self.button2.alpha = 0.0;
[UIView animateWithDuration:0.25
delay:0.5
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.button1.alpha = 1.0;
self.button2.alpha = 1.0;
}
completion:nil];
這並不吃虧NSTimer
對象的保留問題,以及執行兩種延遲以及按鈕的優美顯示都在一個聲明中。如果您在showButtons
方法中進行額外處理,則可以將其放入completion
塊中。
如果您在屬性保存它,那麼,你就需要將其設置爲nil之後它發射的選擇。
如果你的班級由於某種原因被重新分配,那麼保存它也是安全的,這樣如果你需要,你可以[timer invalidate]
。
如果你讓該屬性'weak',你不必'nil'它自己。它會在火災發生後自動釋放(假設它是不重複的)。 – Rob
是的,你可以使用:myTimer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];
,然後在viewDidDisappear [myTimer invalidate]
很好的答案,但也許我沒有說清楚,事實上我並沒有用NSTimer * timer在.h文件中實際解密它,我只是在.m文件中添加該代碼,所以我不能使它失效或零。在這種情況下,如果我使用我的計時器,它還是可以的,還是使用您提供給我的代碼更好? – Alessandro
@Alessandro我其實推測你沒有爲這個計時器維持一個ivar。但是,顯然,如果你想在'viewWillDisappear'中'使'失效',你必須這樣做。 (順便說一句,你不必將私有ivars放在你的.h文件中;私有類擴展更好。)並且你提到過有關將'NSTimer'設置爲'nil'的幾次。請注意,這不能解決強參考週期。定時器或者需要完成(而不是重複),或者你需要「無效」(使用你的新伊娃)。 – Rob