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迴圈引用iOS
- 如何在 iOS 中解決迴圈引用的問題iOS
- iOS 關於NSTimer的迴圈引用iOS
- ios 避免迴圈引用iOS
- Swift中的迴圈強引用 【使用無主引用解決】Swift
- 怎麼解決引用計數 GC 的迴圈引用問題?GC
- Swift解決【閉包引起的迴圈強引用】Swift
- ARC下的block導致的迴圈引用問題解析BloC
- SpringBoot 迴圈引用解決辦法Spring Boot
- NSTimer迴圈引用的幾種解決方案
- Spring如何解決迴圈引用Spring
- 【FastJSON】解決FastJson中“$ref 迴圈引用”的問題ASTJSON
- Python迴圈引用是什麼?如何避免迴圈引用?Python
- iOS 進階 - 記憶體管理(八) -- 迴圈引用iOS記憶體
- 理解 ARC 下的迴圈引用
- require()迴圈引用問題UI
- Swift中的迴圈強引用 【使用無主引用以及隱式解析可選屬性解決】Swift
- Unity容器建構函式引數迴圈引用問題及解決Unity函式
- FastJson中迴圈引用的問題ASTJSON
- 解決NSTimer迴圈引用導致記憶體洩漏的六種方法記憶體
- [NG] 考古 - HttpInterceptor 迴圈引用錯誤HTTP
- JavaScript 深複製的迴圈引用問題JavaScript
- spring解決迴圈依賴Spring
- 全域性元件實現遞迴樹,避免迴圈引用元件遞迴
- ARC記憶體管理以及迴圈引用記憶體
- Vue.js 元件 – 元件間的迴圈引用示例Vue.js元件
- 解決rpm包迴圈依賴
- 如何解決使用JSON.stringify時遇到的迴圈引用問題JSON
- Swift - 使用 Protocol 避免框架之間迴圈引用SwiftProtocol框架
- JavaScript的map迴圈、forEach迴圈、filter迴圈、reduce迴圈、reduceRight迴圈JavaScriptFilter
- iOS-Block全解iOSBloC
- Spring的3級快取和迴圈引用的理解Spring快取
- Xcode8除錯黑科技:Memory Graph實戰解決閉包引用迴圈問題XCode除錯
- 迴圈引用導致的json序列化失敗JSON