日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

object-c编程tips-timer

發布時間:2024/8/26 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 object-c编程tips-timer 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

object-c定時器

object-c定時器會自己主動retain當前的使用者,假設不注意調用invalidate,則非常easy引起循環引用導致內存泄露。以下的思路提供了一套還算可行的解決方式。


舉例:

常常在viewController中有可能有自己主動刷新界面的需求。 獲取數據失敗后。每隔10秒自己主動刷新又一次獲取數據,這個時候使用NSTimer是一個非常方便的事情。普通情況下直接創建一個NSTimer的repeat對象,然后實現相應的timerFireMethod方法。 當用戶主動點擊返回button時候,此界面應該被釋放。可是因為NSTimer retain了當前的viewController,導致界面內存泄露。 你可能會說在dealloc中調用invalidate,可是必須明確dealloc根本就不會調用,當然viewDidDisappear也一樣不會被調用。


前一段時間看了effective object-c,學習了一種非常好的思想,現分享出來。

給NSTimer加入一個類別,使用block的方式傳遞timerFireMethod。代碼例如以下:

@implementation NSTimer(LPBLocks)+(NSTimer*) lpScheduleTimerWithTimerInternal:(NSTimeInterval)intervalblock:(void(^)())blockrepeats:(BOOL)repeats {return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(lpTimerBlockInvoke:) userInfo:[block copy] repeats:repeats]; } +(void)lpTimerBlockInvoke:(NSTimer*)timer {void(^block)() = timer.userInfo;if(block){block();} } @end
這個scheduledTimer方法也會retain target,可是因為這是一個類方法。它保留的是類對象,因此也就不會有什么問題。

它傳入要運行的block, 然后在回調函數中通過userInfo得到block,并運行。


改進:

這個已經是一個非常大的改進了。我們能夠在代碼中放心的傳入block代碼。只是細致思考一下。假設在block中引入了viewController的成員,并且timer又作為成員變量存在于viewController中。

比如例如以下的代碼:

@interface LPNextViewController () {NSTimer* refreshTimer; }
這樣viewController和refreshTimer又陷入了循環引用的邏輯圈里。當然能夠在block中使用weak_self的方式避免循環引用,可是寫起代碼來總是有些不順手。并且還必需要外部使用者顯式的進行。

于是非常easy想到。應該封裝到一個專門的LPTimer類中。它負責持有NSTimer。同一時候NSTimer的block使用LPTimer的weak版本號。

@interface LPTimer () {NSTimer* _pollTimer;//timer selector__weak id _weak_target;SEL _selector;id _userInfo; } @end
-(void)scheduleTimerWithTimerInternal:(NSTimeInterval)intervaltarget:(id)targetselector:(SEL)aSelectoruserInfo:(id)userInforepeats:(BOOL)repeats {__weak id weak_self = self;_weak_target = target;_selector = aSelector;_userInfo = userInfo;//借用第一個版本號的block思想//使用了第二層間接,調用_weak_target的aSelector方法。//這樣能夠把stopTimer給封裝進去。外部不須要管理timer的stop。_pollTimer = [NSTimer lpScheduleTimerWithTimerInternal:1 block:^{[weak_self doTimer];} repeats:repeats]; }
上面的代碼LPTimer持有NSTimer對象。而NSTimer運行的block使用的是weak_self。

它在timer觸發的時候調用自身的doTimer方法。在doTimer中負責將方法傳遞給外部的使用者。

-(void)doTimer {if ([_weak_target respondsToSelector:_selector]) {[_weak_target performSelector:_selector withObject:self];}else{DLog(@"WARNNING: unknown selector");} }

_weak_target是外部的使用者。 外部的使用者能夠將LPTimer看成是一個普通的對象即可,持有它也不會有什么問題。 LPTimer保留一個弱引用指向外部的使用者。在時間到timer觸發的時候,會先調到NStimer的block中。然后傳遞到LPTimer的doTimer中。然后調用到_weak_target的selector中。


必須注意釋放NStimer對象,在LPTimer釋放的時候調用NSTimer的invalidate方法。

-(void)stopTimer {DLog(@"");[_pollTimer invalidate]; } -(void)dealloc {[self stopTimer];DLog(@""); }


事實上。使用者都是使用的LPTimer類,那么應該讓LPTimer表現的和NSTimer的行為一模一樣, 使用組合方式的適配器模式就能夠輕松搞定。


總結:

主要的思想就是NSTimer會retain一個對象,如今讓它retain類對象。

當時候到來進行觸發的時候,由NSTimer類對象觸發到Block中。繼而觸發到外部的LPTimer普通對象中。

在普通對象中我們就能夠自由的進行處理了。使用weak_target使LPTimer弱引用外部使用者,斷開外部使用者與LPTimer的關聯。

使用weak_self斷開LPTimer與NStimer的循環關聯。 個人覺得還算不錯的思想, 有須要的歡迎討論。





轉載于:https://www.cnblogs.com/yxwkf/p/5116280.html

總結

以上是生活随笔為你收集整理的object-c编程tips-timer的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。