RunLoop使用方法
- (void)viewDidLoad {
[super viewDidLoad];
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(execute) object:nil];
[self.thread start];
}
- (void)run
{
NSLog(@"----------run----%@", [NSThread currentThread]);
// 需要向runloop中加入timer/source(Port)/observer等runloop才不会退出
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
}
// 调用该方法随时可以进入runloop执行操作
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];
}
// 此方法也可以保持runloop
- (void)execute
{
// scheduledTimer这个方法把timer直接加进runloop了,不需要手动添加
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(test) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
// 此种方法需要自己添加到runloop中启动
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
}
- (void)timer {
//调用scheduledTimer返回的定时器,已经自动被添加到当前runloop中,而且是NSDefaultRunLoopMode
// [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
//定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
//[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
//定时器只运行在UITrackingRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
//[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
//定时器在NSRunLoopCommonModes下,两种模式下都可以工作
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)observer{
//添加observer
/*
activity的状态值
kCFRunLoopEntry = (1UL << 0), 1 即将进入runloop
kCFRunLoopBeforeTimers = (1UL << 1), 2 即将处理timer
kCFRunLoopBeforeSources = (1UL << 2), 4 即将处理Source
kCFRunLoopBeforeWaiting = (1UL << 5), 32 即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), 64 刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), 128 即将退出runloop
kCFRunLoopAllActivities = 0x0FFFFFFFU
可以监听按钮点击之前的时间
*/
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"-----监听到runloop状态发生改变%zd",activity);
});
// 添加观察者,监听Runloop的状态
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
// 释放observer
CFRelease(observer);
/*
CF的内存管理
1.凡是带有create、copy、retain等字眼的函数,创建出来的对象 最后要做一次release
2、release函数,CFRelease(observer)
*/
}
RunLoop面试题
-
什么是RunLoop
-
从字面意思看,就是运行循环、跑圈
-
其实它内部就是do-while循环,在这个循环内部不断处理各种任务(比如Source、Timer、Observer)
-
一个线程对应一个runloop,主线程的runloop默认已经启动,子线程的 runloop得手动启动,调用run方法
-
runloop只能选择一个Model启动,如果当前model中没有Source、timer、observer,那么就直接退出runloop
-
自动释放池什么时候释放?
-
在RunLoop睡眠之前释放(BeforeWaiting)
-
在开发中如何使用RunLoop?什么应用场景?
开启一个常驻线程,让一个子线程不进入消亡状态,等待其他线程发来消息,处理事件,比如: -
在子线程中开启一个定时器
-
在子线程中进行一些长期监控
-
可以控制定时器在特定模式下执行
-
让某些事件在特定模式下执行
-
可以添加observer监听RunLoop的状态,比如监听点击事件的处理
网友评论