NSObject类提供了很多方法供我们使用,这些方法是添加到runloop的,所以如果没有开启runloop的话,不会运行(不过有个坑,请看下面介绍)。
- /// 主线程
- performSelectorOnMainThread:withObject:waitUntilDone:
- performSelectorOnMainThread:withObject:waitUntilDone:modes:
- /// 指定线程
- performSelector:onThread:withObject:waitUntilDone:
- performSelector:onThread:withObject:waitUntilDone:modes:
- /// 针对当前线程
- performSelector:withObject:afterDelay:
- performSelector:withObject:afterDelay:inModes:
- /// 取消,在当前线程,和上面两个方法对应
- cancelPreviousPerformRequestsWithTarget:
- cancelPreviousPerformRequestsWithTarget:selector:object:
下面提供的方法是在指定的线程运行aSelector
,一般情况下aSelector
会添加到指定线程的runloop。但,如果调用线程和指定线程为同一线程,且wait
参数设为YES,那么aSelector
会直接在指定线程运行,不再添加到runloop。
- performSelectorOnMainThread:withObject:waitUntilDone:
- performSelectorOnMainThread:withObject:waitUntilDone:modes:
-
- performSelector:onThread:withObject:waitUntilDone:
- performSelector:onThread:withObject:waitUntilDone:modes:
其实这也很好理解,假设这种情况也添加到指定线程的runloop,我们可以这样反向理解:
1、当前线程runloop还没有开启,那么aSelector
就不会被执行,然而你却一直在等待,造成线程卡死。
2、当前线程runloop已经开启,那么调用performSelector
这个方法的位置肯定是处于runloop的callout方法里面,在这里等待runloop再callout从而调用aSelector
方法完成,显然也是死等待,线程卡死。。。
还有一些performSelector
方法,是不会添加到runloop的,而是直接执行,可以按照上面的特殊情况进行理解。方法列举如下:
- - (id)performSelector:(SEL)aSelector;
- - (id)performSelector:(SEL)aSelector withObject:(id)object;
- - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
看到这里,是否感觉有些乱???只要记住没有延迟或者等待的都不会添加到runloop,有延迟或者等待的还有排除上面提到的特殊情况。