查看答案
Runloop
是一种循环机制,在不需要处理事件时候休眠,在需要处理事件时候唤醒处理事件。Runloop
就是让线程不退出,随时能处理事件的一种机制。
查看答案
Runloop
和线程是一一对应的,存在于全部的字典当中。线程创建的时候是没有对应Runloop
的,只有获取当前Runloop
才会创建,Runloop
会在线程结束销毁。
查看答案
Runloop
存在五种运行mode
,NSTimer
默认运行在default mode
上面的,当列表滚动的时候,切换称Tracking Mode
。default mode
就会暂停,这就是为什么NStimer
在列表滚动时候失效,解决的办法将NStimer
添加到common mode
里面。
查看答案
- 保持应用的持续运行
- 处理App的各种事件
- 节省CPU资源,提升性能。
- 负责渲染界面的UI
查看答案
-
获取主线程对应的
Runloop
[NSRunLoop mainRunLoop]
-
获取当前线程对应的
RunLoop
[NSRunLoop currentRunLoop]
查看答案
RunLoop
进行处理事件的时候会自动创建一个AutoreleasePool
,在处理事件过程中会将发送autorelease
消息的对象添加到AutoreleasePool
中。等待RunLoop
处理事件结束,就释放当前的AutoreleasePool
。AutoreleasePool
则会将所有的对象进行release
-1操作。
查看答案
@autoreleasepool {
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
[runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runloop run];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"2");
[self performSelector:@selector(test) withObject:nil afterDelay:10];
NSLog(@"3");
});
NSLog(@"4");
}
- (void)test {
NSLog(@"5");
}
查看答案
输出顺序是1 4 2 3
,因为 performSelector:withObject:afterDelay
会自动创建一个NSTimer
添加到当前的RunLoop中,但是当前线程没有获取RunLoop,所以不存在RunLoop,所以对应方法创建的NSTimer
也不会运行,自然不会运行test
方法。
查看答案
因为滑动操作当前的RunLoop运行在Tracking Mode
上面,为了不打断用户的操作,我们可以在Default Mode
上面进行刷新数据,也就是等待滑动结束之后,当前的RunLoop从Tracking Mode
切换到Default Mode
再去更新数据。
[self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
查看答案
GCD只有在回到主线程的时候才会获取当前的RunLoop,会触发RunLoop的Source1事件。