美文网首页
iOS开发 runloop理解

iOS开发 runloop理解

作者: leesen | 来源:发表于2020-04-26 16:37 被阅读0次

介绍:

“消息”循环,等待消息(会休眠)->接收消息->处理消息。通过上面的代码,runloop本质就是提供了一种消息处理模式,只不过它封装抽象的太好了(一般开发的时候根本就感觉不到,或者说不用关心)。

runloop相当于帮我们打包了各种消息,并将消息发送给指定的接受者。“

可以将runloop理解为一个函数,功能是一个消息循环,有消息则处理,没有消息则休眠。

(注意:runloop实质是一个对象,但是不影响以上的假设)

线程刚创建时并没有 RunLoop,如果你不主动获取,那它一直都不会有。RunLoop 的创建是发生在第一次获取时,RunLoop 的销毁是发生在线程结束时。你只能在一个线程的内部获取其 RunLoop(主线程除外)。

系统为我们提供了多种模式,下面列一些比较常遇到的:

kCFRunLoopDefaultMode: App的默认 Mode,通常主线程是在这个 Mode 下运行的。

UITrackingRunLoopMode: 界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响。

UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用。

NSRunLoopCommonModes: 包含了多种模式:default, modal, 和tracking modes。

参考:

NSRunLoop原理详解——不再有盲点 

iOS runloop和线程有什么关系? 

iOS - run loop详解 - 简书

iOS面试题:runloop 和线程有什么关系? 

runloop 和线程的关系:

1 run oop和线程是紧密相连的,可以这样说run loop是为了线程而生,没有线程,它就没有存在的必要。Run loops是线程的基础架构部分

2 一条线程对应一个RunLoop对象,每条线程都有唯一一个与之对应的RunLoop对象。

3 我们只能在当前线程中操作当前线程的RunLoop,而不能去操作其他线程的RunLoop。

4 RunLoop对象在第一次获取RunLoop时创建,销毁则是在线程结束的时候。

5 主线程的RunLoop对象系统自动帮助我们创建好了(原理如下),而子线程的RunLoop对象需要我们主动创建。

使用:

1、NSTimer的创建使用

当实例化NSTimer对象的时候,通常会使用 scheduledTimerWithTimeInterval 方法。该方法会自动为我们实例化的timer添加到当前线程的RunLoop中,并且默认模式是 NSDefaultRunLoopMode。但当前线程是主线程时,某些UI事件,比如ScrollView正在拖动,将会RunLoop切换成 NSEventTrackingRunLoopMode 模式,在这个模式下,默认的 NSDefaultRunLoopMode 模式中注册的事件是不会执行的。也就是说,使用 scheduledTimerWithTimeInterval 方法添加到RunLoop中的Timer就不会执行。

为了设置一个不被UI干扰的Timer,我们需要手动创建一个Timer,然后使用RunLoop的 addTimer:forMode: 方法来把Timer按照指定的模式加入到RunLoop中。这里使用 NSRunLoopCommonModes 模式,这个模式相当于 NSDefaultRunLoopMode 和 NSEventTrackingRunLoopMode 的结合。

2 ImageView推迟显示

一些动画执行过程中,

或者scrllview滑动过程汇总image的显示

[cell performSelector:@selector(setImage)withObject:nil afterDelay:0 inModes:@[NSDefaultRunLoopMode]];

[imageview performSelector: inModes: ]

3 后台常驻线程(很常用)

我们在开发应用程序的过程中,如果后台操作特别频繁,经常会在子线程做一些耗时操作(下载文件、后台播放音乐等),我们最好能让这条线程永远常驻内存。

那么怎么做呢?

添加一条用于常驻内存的强引用的子线程,在该线程的RunLoop下添加一个Sources,开启RunLoop。

具体实现过程如下:

在项目的ViewController.m中添加一条强引用的thread线程属性,如下图:

在viewDidLoad中创建线程self.thread,使线程启动并执行run1方法,代码如下。在Demo中,请在viewDidLoad调用[self showDemo4];方法。

运行之后发现打印了----run1-----,而未开启RunLoop则未打印。

这时,我们就开启了一条常驻线程,下边我们来试着添加其他任务,除了之前创建的时候调用了run1方法,我们另外在点击的时候调用run2方法。

那么,我们在touchesBegan中调用PerformSelector,从而实现在点击屏幕的时候调用run2方法。具体代码如下:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{       //利用performSelector,在self.thread的线程中调用run2方法执行任务

    [self performSelector:@selector(run2)onThread:self.thread withObject:nil waitUntilDone:NO];

}

-(void)run2

{

    NSLog(@"----run2------");

}

经过运行测试,除了之前打印的----run1-----,每当我们点击屏幕,都能调用----run2------

这样我们就实现了常驻线程的需求。

作者:进击的阿牛哥

链接:https://www.jianshu.com/p/f47ec06097ef

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章

  • iOS知识点(10)RunLoop

    深入理解RunLoop iOS---实例化讲解RunLoop iOS runloop iOS-RunLoop充满灵...

  • Objective-C RunLoop 详解

    本文转自ibireme的《深入理解RunLoop》 RunLoop 是 iOS 和 OSX 开发中非常基础的一个概...

  • iOS精读文章

    iOS精读文章摘自 故胤道长 App 开发 深入理解 RunLoop CPU vs GPU · iOS 核心动画...

  • iOS开发 runloop理解

    介绍: “消息”循环,等待消息(会休眠)->接收消息->处理消息。通过上面的代码,runloop本质就是提供了一种...

  • RunLoop详解

    此文转载自深入理解RunLoop,为了方便自己阅读,发在简书上RunLoop 是 iOS 和 OS X 开发中非常...

  • 深入理解RunLoop

    本文转载自ibireme的:深入理解RunLoop RunLoop 是 iOS 和 OSX 开发中非常基础的一个概...

  • iOS开发 Runloop机制

    iOS开发 Runloop机制

  • RunLoop分析

    来源:『深入理解RunLoop』RunLoop 是 iOS 和OSX开发中非常基础的一个概念,这篇文章将从CFRu...

  • 深入理解RunLoop

    深入理解RunLoop由 ibireme | 2015-05-18 | iOS, 技术RunLoop 是 iOS ...

  • 内存管理篇,RunLoop

    iOS内存管理 RunLoop理解

网友评论

      本文标题:iOS开发 runloop理解

      本文链接:https://www.haomeiwen.com/subject/jthjwhtx.html