经常碰到这个词,平常又很少用到,对此模棱两可,遂整理下。

根据苹果官方文档,总结如下:

Run Loops 的目的是当有活要干的时候就开始干,没活干的时候就睡大觉。

NSRunLoop 对象处理的是输入源,如窗体上的键盘输入事件,NSPort 对象,NSConnection 对象等。NSRunLoop 对象同样处理 NSTimer 事件。NSTimer 不是一个真正意义上的输入源,它是一个特殊的类型,当 NSTimer 对象解除时,不会使 NSRunLoop 返回。

不需要直接创建或显示的管理 NSRunLoop 对象,所有的线程包括主线程,NSRunLoop 对象已经自动创建好了。如果需要访问当前线程的 Run Loop,直接使用[NSRunLoop currentRunloop]就 OK 啦!

什么时候使用 NSRunLoop 对象

前提是在除主线程外的次级线程中(主线程默认已经自动开启了)

NSPort 对象

备注:这个不是很熟悉,详见 AFNetworking 源码

1
2
3
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];

线程间交互

举个栗子,在自定义异步线程里中使用 NSURLConnection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//异步
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download) object:nil];
[thread start];
//下载数据
- (void)download {
@autoreleasepool {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.sinaimg.cn/dy/slidenews/4_img/2014_50/704_1502763_259801.jpg"]];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
[[NSRunLoop currentRunLoop] run];
}
}
#pragma mark -
#pragma mark - NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(@"接收响应");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"接收数据...");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"完成");
}

NSTimer 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//异步
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(myTimer) object:nil];
[thread start];
- (void)myTimer {
NSTimer *myTimer = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(executeMyTimer) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
}
- (void)executeMyTimer {
NSLog(@"我的Timer执行啦");
}

参考文章

苹果官方文档 1
苹果官方文档 2
自己调研的一些关于 NSRunLoop 与 NSTimer 的知识