qidao123.com技术社区-IT企服评测·应用市场

标题: 【iOS】—— Runloop和多线程问题总结 [打印本页]

作者: 梦应逍遥    时间: 2024-8-14 01:41
标题: 【iOS】—— Runloop和多线程问题总结
runloop总结

1. runloop简介

runloop是一种高级的循环机制,让程序持续运行,并处理程序中的事件,让线程在须要的时候忙起来,不须要的时候休眠。
主线程的runloop包管应用程序的存活,从而可以实时接收到用户的响应,可以或许触发事件。
2. runloop的基本作用

保持程序持续运行,节省CPU资源,提高程序性能。
3. 获取runloop的流程

程序开始时第一次获取runloop的时候,一定获取的是主线程的runloop。在获取runloop的函数中会定义一个全局的字典变量,该字典是以线程为key,获取的runloop为value,生存到字典中。方便之后获取runloop的时候可以先遍历字典找一找之前有没有获取。如果字典没有对应的runloop,再获取对应线程的runloop。
4. runloop和线程的关系

5. runloop中的Mode有几种以及作用

runloop中有5种Mode:

一个RunLoop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer

常用的有三种Mode:

6.runloop的事件源

输入源:通常用于处理基于文件描述符的事件,可以将外部事件与runloop关联起来,使runloop可以监听这些事件,而且举行相应的处理。
定时源:用于在指定时间隔断触发事件,实用于须要定期实验的任务。通过定时器在特定的时间触发回调方法。
7. 讲一下source0和source1

source0和source1都属于CFRunLoopSourceRef,而CFRunLoopSourceRef是对于输入事件源的抽象。
source0和source1都是在runloop中描述事件的触发机制。source0用于处理手动触发的事件,source1用于处理系统或者其他线程之间的事件。
source0(不会叫醒runloop):

source1(会叫醒runloop):

示例:
用户用手辅导击app界面时,会先触摸到硬件,屏幕会将这个事件先包装成Event,Event先告诉source1(mach_port)叫醒runloop,然后将这个事件Event分发给source0,让source0处理该事件。
8. runloop的六种观察者模式

  1. //观测的时间点有一下几个
  2. typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
  3.     kCFRunLoopEntry = (1UL << 0),   //   即将进入RunLoop
  4.     kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理Timer
  5.     kCFRunLoopBeforeSources = (1UL << 2), // 即将处理Source
  6.     kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
  7.     kCFRunLoopAfterWaiting = (1UL << 6),// 刚从休眠中唤醒
  8.     kCFRunLoopExit = (1UL << 7),// 即将退出RunLoop
  9.     kCFRunLoopAllActivities = 0x0FFFFFFFU
  10. };
复制代码
9. 针对定时器在滑动时停止工作的问题

10. 如何解决定时器不准确的原因

怎样解决:

11. 什么是常驻线程,线程保活


多线程

1. 队多线程的明白

好处


弊端


2. iOS多线程的方式有哪几种

实现多线程的方法:

更倾向于GCD和NSOperation,封装更高级,使用起来更方便。
3. 有效过GCD吗

  1.   //让处理在主线程中执行
  2.         dispatch_async(dispatch_get main_queue(), ^{
  3.                 /*
  4.                  *只在主线程可以执行的处理
  5.                  *例如用户界面更新
  6.                  */
  7.         });
复制代码
  1. - (void)once {        //GCD的一次性代码(只执行一次)
  2.     static dispatch_once_t onceToken;
  3.     dispatch_once(&onceToken, ^{
  4.         // 只执行1次的代码(这里面默认是线程安全的)
  5.     });
  6. }
复制代码
  1. - (void)after {
  2.     NSLog(@"run -- 0");
  3.     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  4.         // 2秒后异步执行这里的代码...
  5.        NSLog(@"run -- 2");
  6.     });
  7. }
复制代码
  1.      dispatch_semaphore_t semalook = dispatch_semaphore_create(1);
  2.    
  3.     dispatch_async(dispatch_get_global_queue(0, 0), ^{
  4.         dispatch_semaphore_wait(semalook, DISPATCH_TIME_FOREVER);
  5.         NSLog(@"1开始");
  6.         sleep(2);
  7.         NSLog(@"1结束");
  8.         dispatch_semaphore_signal(semalook);
  9.     });
  10.    
  11.     dispatch_async(dispatch_get_global_queue(0, 0), ^{
  12.         dispatch_semaphore_wait(semalook, DISPATCH_TIME_FOREVER);
  13.         NSLog(@"2开始");
  14.         sleep(2);
  15.         NSLog(@"2结束");
  16.         dispatch_semaphore_signal(semalook);
  17.     });
复制代码
4. GCD的队列类型

可以使用dispatch_queue_create来创建对象,须要传入两个参数,第一个参数表示队列的唯一标识符,用于DEBUG,可为空;第二个参数用来识别是串行队列还是并发队列。DISPATCH_QUEUE_SERIAL表示串行队列,DISPATCH_QUEUE_CONCURRENT表示并发队列。
  1. // 串行队列的创建方法
  2. dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);
  3. // 并发队列的创建方法
  4. dispatch_queue_t queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);
复制代码
5. NSOperationQueue和GCD的区别以及上风

区别:

6. 线程安全的处理本领


  1. @synchronized (self) {
  2.     // 访问共享资源的代码
  3. }
复制代码

  1. os_unfair_lock_t lock = &(OS_UNFAIR_LOCK_INIT);
  2. os_unfair_lock_lock(lock);
  3. // 访问共享资源的代码
  4. os_unfair_lock_unlock(lock);
复制代码

  1. dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
  2. dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
  3. // 访问共享资源的代码
  4. dispatch_semaphore_signal(semaphore);
复制代码

  1. @property (atomic, strong) NSObject *sharedObject;
复制代码

  1. dispatch_queue_t serialQueue = dispatch_queue_create("com.example.serialQueue DISPATCH_QUEUE_SERIAL);
  2. dispatch_async(serialQueue, ^{
  3.     // 访问共享资源的代码
  4. });
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4