RunLoop 在应用中的基本使用

RunLoop应用场景

  1. 开启一个常驻线程(让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件)
    • 在子线程中开启一个定时器(或添加port)
    • 在子线程中进行一些长期监控
  2. 可以控制定时器在哪种模式下运行
  3. 可以让某些事件(行为、任务)在特定模式下执行
  4. 可以添加Observer监听RunLoop的状态,比如监听点击事件的处理(在所有点击事件之前做一些事情)

常驻线程

让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件

  1. 声明一个NSThread属性:@property (nonatomic, strong) NSThread *thread;
  2. 开启线程
- (void)viewDidLoad {
    [super viewDidLoad];
    self.thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
    [self.thread start];
}

- (void)run {
    // RunLoop如果当前mode中没有任何Sources(Source0、Source1)、Timer,那么就会直接退出RunLoop
    @autoreleasepool {
        // 在此线程开启RunLoop ---> 让线程不死
        [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; // 添加port相当于添加Source
        [[NSRunLoop currentRunLoop] run]; 
    }
}

注意:常驻线程启动RunLoop最好放到autoreleasepool里面
作用:清掉创建的临时变量(主线程的RunLoop会自动在RunLoop睡眠前释放旧的释放池然后自动创建新的释放池,子线程的RunLoop最好添加个大释放池包裹住)

  1. 往常驻线程中发送消息
[self performSelector:@selector(work) onThread:self.thread withObject:nil waitUntilDone:NO];

常驻线程的好处

  • 让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件(AFNetworking框架里面就使用了常驻线程)

定时器与RunLoop

控制定时器在哪种模式下运行

NSTimer:

  • scheduledTimerWithTimeInterval ---- 自动添加到当前RunLoop中,而且是NSDefaultRunLoopMode,可手动修改模式
  • timerWithTimeInterval ---- 需要手动添加到runLoop
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timer) userInfo:nil repeats:YES];
// 将定时器放入RunLoop中
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

模式:

  • NSDefaultRunLoopMode:一旦RunLoop进入其他模式(例如滚动的mode),这个定时器就不会工作
  • NSRunLoopCommonModes:将定时器加入到标记为common modes的模式下,只要RunLoop知道有这个模式的存在,不管RunLoop在哪个模式都会执行这个标记的模式(即使在滚动的UITrackingRunLoopMode下也会执行)

Observer与RunLoop

添加Observer监听RunLoop的状态,比如监听点击事件的处理(在所有点击事件之前做一些事情)

// 创建观察者
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    // 状态改变时回调的block
    NSLog(@"RunLoop状态 %lu",activity);
});
    
// 添加观察者:监听RunLoop的状态
// 参数1:线程的RunLoop对象
// 参数2:观察者
// 参数3:需要监听RunLoop对象所在的模式
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
    
// ARC模式下C语言层面的对象需要手动释放内存
// 释放Observer
CFRelease(observer);

注意:创建了Observer记得要release

RunLoop的状态

  • kCFRunLoopEntry = (1UL << 0), //即将进入loop 1
  • kCFRunLoopBeforeTimers = (1UL << 1), //即将处理Timer 2
  • kCFRunLoopBeforeSources = (1UL << 2), //即将处理Sources 4
  • kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠 32
  • kCFRunLoopAfterWaiting = (1UL << 6), //刚从休眠中唤醒 64
  • kCFRunLoopExit = (1UL << 7), //即将退出loop 128
  • kCFRunLoopAllActivities = 0x0FFFFFFFU //所有状态
UL是无符号长整数的意思
    1UL<<0:0b00000001
    1UL<<1:0b00000010
    1UL<<2:0b00000100
    1UL<<3:0b00001000
0x0FFFFFFF是整形int变量里能保存的最大数

让某些事件(行为、任务)在特定模式下执行

设置图片不在滚动视图滚动期间显示

[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"01"] afterDelay:3.0 inModes:@[NSDefaultRunLoopMode]];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 一、什么是runloop 字面意思是“消息循环、运行循环”。它不是线程,但它和线程息息相关。一般来讲,一个线程一次...
    WeiHing阅读 8,101评论 11 111
  • ======================= 前言 RunLoop 是 iOS 和 OSX 开发中非常基础的一个...
    i憬铭阅读 859评论 0 4
  • runtime 和 runloop 作为一个程序员进阶是必须的,也是非常重要的, 在面试过程中是经常会被问到的, ...
    made_China阅读 1,198评论 0 7
  • runtime 和 runloop 作为一个程序员进阶是必须的,也是非常重要的, 在面试过程中是经常会被问到的, ...
    SOI阅读 21,753评论 3 63
  • RunLoop 文章目录 RunLoop简介 1.1 什么是RunLoop? 1.2 RunLoop和线程 1.3...
    May_d8f1阅读 279评论 0 1