在iOS中NSRunLoop是一个对象,run是它的一个对象方法,runloop嵌套一般指的是在NSRunLoop的run方法中再调用一次run方法,runloop的run方法内部都是开启了一个while循环,因此在run方法中再调用一次run方法则相当于在一个while循环中开启另一个while循环,内层while循环会导致外层while循环的阻塞。
BOOL r1_run = YES;
BOOL r2_run = YES;
while (r1_run) {
NSLog(@"---1-");
while (r2_run) {
}
NSLog(@"---2-");
}
另外,在runloop 中,每开启一个run方法都是在处理runloop 指定mode下的modeItem的事件,如果外层run方法与内层run方法运行的是在同一mode下,那在外层run方法中没来得及处理的modeItem的事件在进入内层run方法后可以继续被处理。
1、练习一
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSTimer *timer1 = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer1 forMode:NSDefaultRunLoopMode];
}
- (void)timerMethod {
NSLog(@"---1");
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
NSLog(@"---2");
}
2、练习二:求下列代码打印顺序
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
[[NSRunLoop currentRunLoop] performBlock:^{
NSLog(@"2");
}];
NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:10 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSLog(@"3");
CFRunLoopStop(CFRunLoopGetCurrent());
}];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:@"mode1"];
[[NSRunLoop currentRunLoop] runMode:@"mode1" beforeDate:[NSDate distantFuture]];
NSLog(@"4");
}
3、练习三:求下列代码打印内容
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadStartMethod) object:nil];
[thread start];
}
- (void)threadStartMethod {
NSTimer *timer1 = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
NSTimer *timer2 = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(timerMethod2) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer1 forMode:@"mode1"];
[[NSRunLoop currentRunLoop] addTimer:timer2 forMode:@"mode1"];
[[NSRunLoop currentRunLoop] runMode:@"mode1" beforeDate:[NSDate distantFuture]];
}
- (void)timerMethod {
NSLog(@"---1");
NSTimer *timer4 = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(timerMethod4) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer4 forMode:@"mode1"];
[[NSRunLoop currentRunLoop] runMode:@"mode1" beforeDate:[NSDate distantFuture]];
NSLog(@"---2");
}
- (void)timerMethod2 {
NSLog(@"---3");
NSTimer *timer3 = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(timerMethod3) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer3 forMode:@"mode1"];
[[NSRunLoop currentRunLoop] runMode:@"mode1" beforeDate:[NSDate distantFuture]];
NSLog(@"---4");
}
- (void)timerMethod3 {
NSLog(@"---5");
// CFRunLoopStop(CFRunLoopGetCurrent());
}
- (void)timerMethod4 {
NSLog(@"---6");
}