iOS | 用於解決迴圈引用的block timer
iOS 10的時候NSTimer
新增了一個帶block的API:
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
蘋果的官方文件裡說,將這個timer本身作為引數傳給block以此來避免迴圈引用:
/// - parameter: block The execution body of the timer; the timer itself is passed as the parameter to this block when executed to aid in avoiding cyclical references
有了這個API再也不需要繁瑣的手動登出timer,結合weakSelf就可以輕鬆處理迴圈引用,如:
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
__strong typeof(self) strongSelf = weakSelf;
[strongSelf printNum];
}];
在這個API出現之前,self和timer的引用關係是:
self->timer->self
現在的引用關係是:
self->timer->weakSelf
但是隻有iOS 10及之後的系統才能使用此API,而我們一般都是適配到iOS 8,所以有必要擴充套件一下。
如何擴充套件?
簡單點,寫個category,直接複製蘋果的API進去(思考API設計的時間都省了?),然後加上字首:
+ (NSTimer *)cq_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block {
return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(cq_callBlock:) userInfo:[block copy] repeats:repeats];
}
+ (void)cq_callBlock:(NSTimer *)timer {
void (^block)(NSTimer *timer) = timer.userInfo;
!block ?: block(timer);
}
你不是把timer作為引數傳給block嗎?那我也這樣搞。
然後就可以像使用系統API那樣使用了:
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer cq_scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer *timer) {
__strong typeof(self) strongSelf = weakSelf;
[strongSelf printNum];
}];
最後提供一個此timer使用的具體demo:
https://github.com/CaiWanFeng/CQCountDownButton
相關文章
- iOS-block迴圈引用詳解和應用iOSBloC
- Block迴圈引用的三種解決方式BloC
- Swift與OC真正去理解Block解決迴圈引用的技巧SwiftBloC
- iOS 關於NSTimer的迴圈引用iOS
- 解決迴圈引用
- iOS迴圈引用iOS
- SpringBoot 迴圈引用解決辦法Spring Boot
- NSTimer迴圈引用的幾種解決方案
- ARC下的block導致的迴圈引用問題解析BloC
- 怎麼解決引用計數 GC 的迴圈引用問題?GC
- 【FastJSON】解決FastJson中“$ref 迴圈引用”的問題ASTJSON
- Spring如何解決迴圈引用Spring
- 迴圈引用
- Python迴圈引用是什麼?如何避免迴圈引用?Python
- iOS 進階 - 記憶體管理(八) -- 迴圈引用iOS記憶體
- 解決NSTimer迴圈引用導致記憶體洩漏的六種方法記憶體
- require()迴圈引用問題UI
- FastJson中迴圈引用的問題ASTJSON
- Unity容器建構函式引數迴圈引用問題及解決Unity函式
- spring解決迴圈依賴Spring
- 如何解決使用JSON.stringify時遇到的迴圈引用問題JSON
- JavaScript 深複製的迴圈引用問題JavaScript
- [NG] 考古 - HttpInterceptor 迴圈引用錯誤HTTP
- 全域性元件實現遞迴樹,避免迴圈引用元件遞迴
- Spring的3級快取和迴圈引用的理解Spring快取
- 【Spring】Spring中的迴圈依賴及解決Spring
- Spring怎麼解決迴圈依賴?Spring
- 使用c#強大的表示式樹實現物件的深克隆之解決迴圈引用的問題C#物件
- iOS block巢狀block中weakify的使用iOSBloC巢狀
- 迴圈引用導致的json序列化失敗JSON
- Swift - 使用 Protocol 避免框架之間迴圈引用SwiftProtocol框架
- iOS Block探究iOSBloC
- spring原始碼之bean的初始化及迴圈引用Spring原始碼Bean
- Spring 迴圈引用(三)原始碼深入分析版Spring原始碼
- 字典功能的應用(迴圈)
- 24--Spring解決bean之間的迴圈依賴SpringBean
- Spring 迴圈依賴的三種方式(三級快取解決Set迴圈依賴問題)Spring快取
- Flask中的迴圈引用/匯入問題演示以及解決方案 | 藍圖的使用與解析 | 藍圖額外用法Flask