一、performSelectorXXX之类的方法
1、performSelectorOnMainThread:withObject:waitUntilDone:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
在主线程上执行指定的方法,使用默认的模式(NSDefaultRunLoopMode)。
默认的模式指:主线程中的方法进行排队,是一个循环队列,并且循环执行。
参数:
aSelector:要在主线程执行的方法,该方法不能有返回值,并且只能有一个参数。
arg:要传递的参数,如果无参数,就设为nil
wait:要执行的aSelector方法,是否马上执行。
如果设置为YES:等待当前线程执行完以后,主线程才会执行aSelector方法;
设置为NO:不等待当前线程执行完,就在主线程上执行aSelector方法。
如果,当前线程就是主线程,那么aSelector方法会马上执行。
该方法用途:因为iPhone编程,对UI的修改,只能在主线程上执行。可以用该方法来完成UI的修改。
2、performSelector:withObject:afterDelay:
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
在当前线程中执行指定的方法,使用默认模式,并指定延迟。
参数:
aSelector:指定的方法。含义同上,不在赘述。
anArgument:同上
delay:指定延迟时间(秒)。
3、performSelector
我们常常用到以下3个方法,分别为:
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
更多参数可以封装字典dictionary再传。
二、NSTimer
先说一下,初始化方法
+ scheduledTimerWithTimeInterval:invocation:repeats:
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
这两个是创建一个定时器,并自动加入到当前运行循环中,即我们可以这样去理解,初始化了一个定时器时,在(NSTimeInterval)seconds 时间之后,自动启动定时器。
但而以下两个初始化方法这不一样:
+ timerWithTimeInterval:invocation:repeats:
+ timerWithTimeInterval:target:selector:userInfo:repeats:
这两个同样是创建,但没有加入到运行循环中,需要手动添加,如下:
_timer=[NSTimer timerWithTimeInterval:10 target:self selector:@selector(changeTimeAtTimedisplay) userInfo:nil repeats:YES];
//必须手动加入到当前循环中去
NSRunLoop *runloop=[NSRunLoop currentRunLoop];
[runloop addTimer:_timer forMode:NSDefaultRunLoopMode];
三、代码验证
- (void)viewDidLoad {
[super viewDidLoad];
//1、在主线程执行调用
[self performSelector:@selector(performOnMainThread) withObject:nil afterDelay:3];
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(scheduledTimerOnMainThread) userInfo:nil repeats:YES];
// 要让 timerWithTimeInterval 这个定时器执行,不行手动加到必须手动加入到当前循环中去
/**
* [NSTimer timerWithTimeInterval:3 target:self selector:@selector(timerWithTimeMethod) userInfo:nil repeats:YES];
* NSRunLoop *runloop=[NSRunLoop currentRunLoop];
* [runloop addTimer:_timer forMode:NSDefaultRunLoopMode];
*
*/
[NSTimer timerWithTimeInterval:3 target:self selector:@selector(timerWithTimeOnMainThread) userInfo:nil repeats:YES];
// 2、在子线程执行调用
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelector:@selector(performOnSubThread) withObject:nil afterDelay:3];
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(scheduledTimerOnSubThread) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(timerWithTimeOnSubThread) userInfo:nil repeats:YES];
});
}
#pragma mark - 延迟执行指定方法
- (void)performOnMainThread {
NSString *thread = [NSThread isMainThread] == 1 ? @"主线程":@"子线程";
NSLog(@"performOnMainThread 方法在 %@ 执行",thread);
NSLog(@"-------------------------------------------------");
}
- (void)performOnSubThread {
NSString *thread = [NSThread isMainThread] == 1 ? @"主线程":@"子线程";
NSLog(@"performonSubThread 方法在 %@ 执行",thread);
NSLog(@"-------------------------------------------------");
}
- (void)scheduledTimerOnMainThread {
NSString *thread = [NSThread isMainThread] == 1 ? @"主线程":@"子线程";
NSLog(@"scheduledTimerOnMainThread 方法在 %@ 执行",thread);
NSLog(@"-------------------------------------------------");
}
- (void)scheduledTimerOnSubThread {
NSString *thread = [NSThread isMainThread] == 1 ? @"主线程":@"子线程";
NSLog(@"scheduledTimerOnSubThread 方法在 %@ 执行",thread);
NSLog(@"-------------------------------------------------");
}
- (void)timerWithTimeOnSubThread {
NSString *thread = [NSThread isMainThread] == 1 ? @"主线程":@"子线程";
NSLog(@"timerWithTimeOnSubThread 方法在 %@ 执行",thread);
NSLog(@"-------------------------------------------------");
}
- (void)timerWithTimeOnMainThread {
NSString *thread = [NSThread isMainThread] == 1 ? @"主线程":@"子线程";
NSLog(@"timerWithTimeOnMainThread 方法在 %@ 执行",thread);
NSLog(@"-------------------------------------------------");
}
结果输出如下:
2016-08-16 11:30:55.776 performSelector[9788:1950942] performOnMainThread 方法在主线程执行
2016-08-16 11:30:55.777 performSelector[9788:1950942] -------------------------------------------------
2016-08-16 11:30:55.777 performSelector[9788:1950942] scheduledTimerOnMainThread 方法在主线程执行
2016-08-16 11:30:55.778 performSelector[9788:1950942] -------------------------------------------------
2016-08-16 11:30:58.776 performSelector[9788:1950942] scheduledTimerOnMainThread 方法在主线程执行
2016-08-16 11:30:58.776 performSelector[9788:1950942] -------------------------------------------------
2016-08-16 11:31:01.776 performSelector[9788:1950942] scheduledTimerOnMainThread 方法在主线程执行
2016-08-16 11:31:01.777 performSelector[9788:1950942] -------------------------------------------------
2016-08-16 11:31:04.776 performSelector[9788:1950942] scheduledTimerOnMainThread 方法在主线程执行
2016-08-16 11:31:04.777 performSelector[9788:1950942] -------------------------------------------------
2016-08-16 11:31:07.776 performSelector[9788:1950942] scheduledTimerOnMainThread 方法在主线程执行
2016-08-16 11:31:07.776 performSelector[9788:1950942] -------------------------------------------------
四、结论
performSelector:withObject:afterDelay 和
[NSTimer timerWithTimeInterval:invocation:repeats:]
放在在子线程中指定的@selecter()不会执行,主线程中可正常使用。因此必须保证调用是在主线程中。因此,可以使用GCD的方式,将此调用放在主线程中执行:
dispatch_async(dispatch_get_main_queue(), ^{ });或者调用
performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait