查看答案
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事件。