在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");
}