IOS - 延遲執行performSelector和取消延遲執行cancelPreviousPerformRequestsWithTarget


IOS開發時可能會想用到延時執行一個函數。學會用這個函數有時會讓代碼簡單很多。

下文出現的self均指當前頁面控制器(ViewController)

基本方法:

 1 @interface NSObject (NSDelayedPerforming)
 2 
 3 //設置延遲執行,delay單位為秒
 4 - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
 5 
 6 - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
 7 
 8 //取消已設置的延遲執行
 9 + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(id)anArgument;
10 
11 + (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;
12 
13 @end

 

如若設置下面的延遲執行方法:

1 [self performSelector:@selector(didRuninCurrModel:) withObject:[NSNumber numberWithBool:YES] afterDelay:3.0f];
2 
3 [self performSelector:@selector(didRuninCurrModelNoArgument) withObject:nil afterDelay:3.0f];

 

若取消對應的延遲執行方法可用下面方法:

1 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(didRuninCurrModel:) object:[NSNumber numberWithBool:YES]];
2 
3 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(didRuninCurrModelNoArgument) object:nil];

 

需要注意的是參數的一致性,如下面的取消無法實現:

1 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(didRuninCurrModel:) object:[NSNumber numberWithBool:NO]];
2 
3 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(didRuninCurrModel:) object:nil];

 

下面方法可以一次取消所有的延遲執行:

1 [NSObject cancelPreviousPerformRequestsWithTarget:self];
2 
3 [[self class] cancelPreviousPerformRequestsWithTarget:self];

 

注意:設置延遲執行可能會導致內存泄漏:

(這個我也不是特別懂,不能說沒遇到過,只是現在的水平還達不到那個高度)

搜集網上的資料說:當頁面需要dealloc時,若延遲函數還沒有執行會引發內存泄漏。

個人認為如果像這樣設置延遲執行:

1 [self performSelector:@selector(function) withObject:self afterDelay:30.0f];

若在頁面需要dealloc時沒有執行延遲函數,從self的引用計數來看應該會出現內存泄漏。

但是不清楚當參數withObject:nil 時會不會改變self的引用計數。

 

另外,我在一次練習中用到了這個延遲執行,但是,最終失敗了,分享一下我當時的做法和現在的一些想法。

TestApp是一個NavigationController控制的二級頁面。當點擊首頁的TableViewCell會跳轉到第二級頁面。然后我的延遲執行是在第二級頁面設置的。延遲執行設置和執行方面正常,但當我設置好延遲執行,返回主頁然后再進入該第二級頁面,無法取消之前設置的延遲執行。

 

NavigationController控制的頁面跳轉,是把頁面控制器放到一個棧里,根據前進還是返回進行入棧和出棧的。后來分析了下,像上面,我第二次進入第二級頁面已經不是第一次進入的那個第二級頁面了,所以不能取消第一次設置的延遲執行。但是延遲執行能夠執行成功,則是說明第一次的那個第二級頁面雖然出棧了但沒有被dealloc掉,這個應該是因為設置延遲執行會增加頁面的引用計數,而和設置引用計數時有沒有設置withObject:self 或者withObject:nil 沒有關系。

 

不知道我的想法對不對,大神不要嘲笑,歡迎指導!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM