performSelector withObject afterDelay 在子線程上調用不運行,performselector
如題,這是最近在修改一個資料同步模組時發現的問題。整個資料同步的任務是在App啟動後放在一個後台執行的線程中的,執行某個單條資料同步任務成功後,會使用
Objective-c代碼
- [self performSelector:(nonnull SEL) withObject:(nullable id) afterDelay:(NSTimeInterval)];
來執行下一個單條資料同步任務。通過調試,發現在執行到這行代碼的時候,並沒有調用 SEL 的方法。在確定存在這個方法後,一直沒有想到原因,於是就Google之。答案就是,performSelector withObject afterDelay 方法在子線程中,並不會調用SEL方法,而 performSelector withObject 方法會直接調用。原因在於一下兩點:
1、afterDelay方式是使用當前線程的定時器在一定時間後調用SEL,NO AfterDelay方式是直接調用SEL。
2、子線程中預設是沒有定時器的。
所以,針對問題的解決方案也有兩種:
1、開啟線程的定時器
Objective-c代碼
- [[NSRunLoop currentRunLoop] run];
2、使用dispatch_after來執行定時任務
Objective-c代碼
- - (void)functionToDelay:(SEL)function param:(nullable id)param afterDelay:(NSTimeInterval)delay {
- dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, delay*NSEC_PER_SEC);
- dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- if ([self respondsToSelector:function]) {
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
- [self performSelector:function withObject:param];
- #pragma clang diagnostic pop
-
- }
- });
- }
QQ技術交流群290551701 http://cxy.liuzhihengseo.com/556.html