iOS开发中关于多线程的问题(NSOperationQueue,NSThread,GCD)
Posted kaihaOS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发中关于多线程的问题(NSOperationQueue,NSThread,GCD)相关的知识,希望对你有一定的参考价值。
1.多线程的优点和缺点分别是什么? 答:优点: 1 、将耗时较长的操作(网络请求、图片下载、音频下载、数据库访问等)放在子线程中执行,可以防止主线程的卡死; 2 、可以发挥多核处理的优势,提升 cpu 的使用率。 缺点: 1 、每开辟一个子线程就消耗一定的资源; 2 、会造成代码的可读性变差; 3 、如果出现多个线程同时访问一个资源,会出现资源争夺的情况 3. 2.NSOperationQueue 中有一个属性叫 maxConcurrentCount 即最大并发数。这里所谓的最大并发数指的是什么含义? 答:这里的最大并发数指得是在队列中同时执行的任务的个数。有很多人会认为是所分配的线程的个数。其实不是的。因为线程的个数的多少取决于系统,系统会分配合适的线程数量来保证这些任务并发执行的,作为程序员我们是没办法控制的 4 、 NSThread 中的 Runloop 的作用,如何使用? 每个线程 (NSThread) 对象中内部都有一个 run loop ( NSRunLoop )对象用来循环处理输入事件,处理的事件包括两类,一是来自 Input sources 的异步事件,一是来自 Timer sources 的同步事件 ; run Loop 在处理输入事件时会产生通知,可以通过 Core Foundation 向线程中添加 run-loop observers 来监听特定事件 , 以在监听的事件发生时做附加的处理工作。 主线程的 Run Loop 会在 App 运行时自动运行,子线程中需要手动运行。 Run Loop 就是一个处理事件源的循环,你可以控制这个 Run Loop 运行多久,如果当前没有事件发生, Run Loop 会让这个线程进入睡眠状态 ( 避免再浪费 CPU 时间 ) ,如果有事件发生, Run Loop 就处理这个事件。 如果子线程进入一个循环需要不断处理一些事件,那么设置一个 Run Loop 是最好的处理方式,如果需要 Timer ,那么 Run Loop 就是必须的。 开发中遇到的需要使用 Run Loop 的情况有: 需要使用 Port 或者自定义 Input Source 与其他线程进行通讯。 子线程中使用了定时器 使用任何 perform mSelector***** 到子线程中运行方法 使用子线程去执行周期性任务 NSURLConnection 在子线程中发起异步请求 10 ) OC 中创建线程的方法是什么?如果在主线程中执行代码,方法是什么 线程创建有三种方法 : 使用 NSThread 创建、使用 GCD 的 dispatch 、使用子类化的 NSOperation, 然后将其加入 NSOperationQueue; 在主线程执行代码 , 方法是 performSelectorOnMainThread, 如果想延时执行代码可以用 performSelector:onThread:withObject:waitUntilDone: 11) 线程和进程的区别和联系 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程 9. 在项目什么时候选择使用 GCD ,什么时候选择 NSOperation ? gcd 是基于 c 的底层 api , NSOperation 属于 object-c 类。 相对于 gcd : 1 , NSOperation 拥有更多的函数可用,具体查看 api 。 2 ,在 NSOperationQueue 中,可以建立各个 NSOperation 之间的依赖关系。 3 ,有 kvo ,可以监测 operation 是否正在执行( isExecuted )、是否结束( isFinished ),是否取消( isCanceld )。 4 , NSOperationQueue 可以方便的管理并发、 NSOperation 之间的优先级。 gcd 主要与 block 结合使用。 项目中使用 NSOperation 的优点是 NSOperation 是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化 NSOperation 的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。 项目中使用 GCD 的优点是 GCD 本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而 Block 参数的使用,会是代码更为易读,建议在简单项目中使用。 1 、线程的堆栈大小 iPhone 设备上的应用程序开发也是属于嵌入式设备的开发,同样需要注意嵌入式设备开发时的几点问题,比如资源上限,处理器速度等。 iPhone 中的线程应用并不是无节制的,官方给出的资料显示 iPhone OS 下的主线程的堆栈大小是 1M ,第二个线程开始都是 512KB 。并且该值不能通过编译器开关或线程 API 函数来更改。 2 、 Autorelease 如果你什么都不考虑,在线程函数内调用 autorelease ,会出现错误 3 、子线程中描画窗口 多线程编程中普遍遵循一个原则,就是一切与 UI 相关的操作都有主线程做,子线程只负责事务,数据方面的处理。那么如果想在子线程中更新 UI 时怎么做呢?如果是在 windows 下,你会 PostMessage 一个描画更新的消息,在 iPhone 中,需要使用 performSelectorOnMainThread 委托主线程处理。 总结: 多线程能适当提高程序的执行效率,能适当提高资源利用率( CPU 、内存利用率),但是开启线程需要占用一定的内存空间(默认情况下,主线程占用 1M ,子线程占用 512KB ),如果开启大量的线程,会占用大量的内存空间,降低程序的性能,而且线程越多, CPU 在调度线程上的开销就越大,使用多线程程序设计更加复杂:比如线程之间的通信、多线程的数据共享 一个 ios 程序运行后,默认会开启 1 条线程,称为“主线程”或“ UI 线程” 主线程的使用注意 : 别将比较耗时的操作放到主线程中。耗时操作会卡住主线程,严重影响 UI 的流畅度,给用户一种“卡”的坏体验 25. 线程是什么?进程是什么?二者有什么区别和联系? ( UI 第二十二讲 多线程编程) 线程是 CPU 独立运行和独立调度的基本单位(可以理解为一个进程中执行的代码片段),进程是资源分配的基本单位(进程是一块包含了某些资源的内存区域)。进程是线程的容器,真正完成代码执行的是线程,而进程则作为线程的执行环境。一个程序至少包含一个进程,一个进程至少包含一个线程,一个进程中的多个线程共享当前进程所拥有的资源。 26. 谈谈你对多线程开发的理解? ios 中有几种实现多线程的方法?( UI 第二十二讲 多线程编程) 好处: ①、使用线程可以把程序中占据时间长的任务放到后台去处理,如图片、视频的下载 ②、发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好 缺点: ①、大量的线程降低代码的可读性, ②、更多的线程需要更多的内存空间 ③、当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。 iOS 有三种多线程编程的技术: ①、 NSThread( 两种创建方式 ) [NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil]; NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil]; [myThread start]; ②、 NSOperationQueue NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init]; oprationQueue addOperationWithBlock:^ // 这个 block 语句块在子线程中执行③、 Grand Central Dispatch (GCD) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ // 耗时的操作 dispatch_async(dispatch_get_main_queue(), ^ // 更新界面 ); );
PS: 不显示的创建线程的方法: 用 NSObject 的类方法 performSelectorInBackground:withObject: 创建一个线程: [Obj performSelectorInBackground:@selector(doSomething) withObject:nil]; 27. 线程同步和异步的区别? IOS 中如何实现多线程的同步? 同步:一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。 异步:同时去做两件或者多件事。比如边听歌边看报。 .runloop 和线程有什么关系? 总的说来, Run loop ,正如其名, loop 表示某种循环,和 run 放在一起就表示一直在运行着的循环。实际上, run loop 和线程是紧密相连的,可以这样说 run loop 是为了线程而生,没有线程,它就没有存在的必要。 Run loops 是线程的基础架构部分, Cocoa 和 CoreFundation 都提供了 run loop 对象方便配置和管理线程的 run loop (以下都以 Cocoa 为例)。每个线程,包括程序的主线程( main thread )都有与之相应的 run loop 对象。 runloop 和线程的关系:主线程的 run loop 默认是启动的。 iOS 的应用程序里面,程序启动后会有一个如下的 main() 函数 int main(int argc, char * argv[]) @autoreleasepool return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 重点是 UIApplicationMain() 函数,这个方法会为 main thread 设置一个 NSRunLoop 对象,这就解释了:为什么我们的应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。 对其它线程来说, run loop 默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动,如果线程只是去执行一个长时间的已确定的任务则不需要。 在任何一个 Cocoa 程序的线程中,都可以通过以下代码来获取到当前线程的 run loop 。 NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 51. GCD 的队列( dispatch_queue_t )分哪两种类型? 串行队列 Serial Dispatch Queue 并行队列 Concurrent Dispatch Queue 77. 你参与的 APP ,是如何处理多个服务的同步发起的? 使用 iOS 线程技术,创建并行队列来分别执行不同的任务。将不同的任务加入到子队列当中,任务执行后回到主线程当中刷新 UI 界面。 APP 界面一般都是根据产品需求和 UI 效果图来完成的,但是我们为了提高代码的复用性,会将视图的实现进行封装,然后在控制器当中进行加载用 88.NSOperationQueue 有哪些使用方式? 一种在 iOS 中执行并发操作的方法,是使用 NSOperation 和 NSOperationQueue 类。在本教程中,你将学习如何使用它们!你会先创建一款不使用多线程的 app ,这样它会变得响应非常迟钝。然后改进程序,添加上并行操作–并且希望–可以提供一个交互响应更好的界面给用户! 另一种处理操作之间的依赖关系,如果操作直接有依赖关系,比如第二个操作必须等第一个操作结束后再执行。控制线程池中的线程数 89.NSThread 中的 Runloop 的作用,如何使用? 有些情况下,我们还是在运行一些长线任务或者复杂任务的时候需要用比较原始的 NSThread 。这就需要为 NSThread 创建一个 run loop. 1 NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(playerThread: ) object:nil]; 2 [thread start]; 3 // 如果要利用 NSOperation ,原理类似。只需要加入到 queue 里面去就好了。。 queue 会在合适的时机调用方法,下面代码作为参考。 4 - (void) playerThread: (void*)unused 5 6 audioRunLoop = CFRunLoopGetCurrent();// 子线程的 runloop 引用 7 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];// 子线程的 8 [self initPlayer]; CFRunLoopRun(); // 运行子线程的 9 [pool release]; // run loop, 这里就会停住了。 10 11 // 实现一个 timer, 用于检查子线程的工作状态,并在合适的时候做任务切换。或者是合适的时候停掉自己的 12 -(void) initPlayer 13 // 在这里你可以初始化一个工作类,比如声音或者视频播放 14 NSTimer *stateChange = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector: 15 @selector(checkStatuserInfo:nil repeats:YES]; 16 17 -(void) checkState:(NSTimer*) timer 18 19 if( 需要退出自线程了 ) 20 // 释放子线程里面的资源 21 CFRunLoopStop( CFRunLoopGetCurrent());// 结束子线程任务 22 23 3. NSThread 、 NSOperationQueue 以及 GCD 等多线程编程技术什么情况下使用? 1 ) NSThread 优点: NSThread 比其他两个轻量级 缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销
2 ) Cocoa NSOperation 优点 : 不需要关心线程管理, 数据同步的事情,可以把精力放在自己需要执行的操作上。 Cocoa operation 相关的类是 NSOperation, NSOperationQueue. NSOperation 是个抽象类 , 使用它必须用它的子类,可以实现它或者使用它定义好的两个子类 : NSInvocationOperation 和 NSBlockOperation. 创建 NSOperation 子类的对象,把对象添加到 NSOperationQueue 队列里执行。 2 ) GCD 使用过程中遇到的问题? 44. 项目中哪块用到多线程,碰到了什么问题,怎么解决的 什么时候使用多线程: 将耗时、轮询或者并发需求高等任务分配到其他线程执行,并由主线程负责统一更新界面会使得应用程序更加流畅,用户体验更好,例如网络请求 , 播放游戏的背景音乐,文件下载等。 碰到的问题以及解决办法: ( 1 )使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢 使用以下方法可以控制并发的线程数量: -(void)setMaxConcurrentOperationCount:(NSInteger)cnt; 使用 addDependency 可以建立操作之间的依赖关系,设定操作的执行顺序 ( 2 )当多个线程对同一个资源出现争夺的时候需要注意线程安全问题 ( 3 )更新 UI 界面,处理界面和用户之间的交互事件一定要在主线程中处理。 ‘多线程中栈与堆是公有的还是私有的 一般来说栈是私有的,堆是公有的;但是可以为特定的线程创建私有的堆 在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。 堆: 是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。 栈:是个线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立,因此,栈是 thread safe的。操作系统在切换线程的时候会自动的切换栈,就是切换 SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。 24、描述runloop和线程的关系 Run loop,正如其名,loop表⽰示某种循环,和run放在⼀一起就表⽰示⼀一直在运⾏行着 的循环。实际上,run loop和线程是紧密相连的,可以这样说run loop是为了线 程⽽而⽣生,没有线程,它就没有存在的必要。Run loops是线程的基础架构部分, Cocoa和CoreFundation都提供了run loop对象⽅方便配置和管理线程的run loop(以 下都已Cocoa为例)。每个线程,包括程序的主线程(main thread)都有与之相 应的run loop对象。 8、GCD的队列(dispatch_queue_t)分哪两种类型?编写代码:使⽤用并⾏行队列 实现多线程开发 串⾏行队列Serial Dispatch Queue 并⾏行队列Concurrent Dispatch Queue 1 dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIO RITY_DEFAULT, 0); 2 dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIO RITY_HIGH, 0); 3 dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIO RITY_LOW, 0);
1 、列举 Cocoa 中常见对几种线程的实现,并谈谈多线程安全的几种解决办法和多线程安全怎么控制 . Cocoa 中常见对几种线程的实现 : (1)OC 的 NSThread (2) C 语言的 GCD 接口(性能最好,代码更精简) (3) OC 的 NSOperation 和 NSOperationQueue (基于 GCD ) 多线程安全的几种解决办法 (1) 只在主线程刷新访问 UI (2) 如果要防止资源抢夺,得用 synchronize 进行加锁保护。 (3) 如果异步操作要保证线程安全等问题,尽量使用 GCD 。( GCD 有些函数默认就是安全的)
19.多线程在实际项目中的应用中有没有碰到什么问题什么时候使用多线程: 将耗时、轮询或者并发需求高等任务分配到其他线程执行,并由主线程负责统一更新界面会使得应用程序更加流畅,用户体验更好,例如网络请求,播放游戏的背景音乐,文件下载等。 碰到的问题以及解决办法: (1)使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢 使用以下方法可以控制并发的线程数量: -(void)setMaxConcurrentOperationCount:(NSInteger)cnt; 使用addDependency可以建立操作之间的依赖关系,设定操作的执行顺序 (2)当多个线程对同一个资源出现争夺的时候需要注意线程安全问题 (3)更新UI界面,处理界面和用户之间的交互事件一定要在主线程中处理 3. 2.NSOperationQueue 中有一个属性叫 maxConcurrentCount 即最大并发数。这里所谓的最大并发数指的是什么含义? 答:这里的最大并发数指得是在队列中同时执行的任务的个数。有很多人会认为是所分配的线程的个数。其实不是的。因为线程的个数的多少取决于系统,系统会分配合适的线程数量来保证这些任务并发执行的,作为程序员我们是没办法控制的 4. 在项目中什么时候选择使用 GCD ,什么时候选择使用 NSOperation ? 答:无论是 GCD 还是 NSOperation 其实都是多线程的一种实现形式。严格的说 NSOperation 和线程并没有必然联系,更不是多线程, NSOperation 只是操作,封装了 target 和 action 或者 Block ,在主线程中执行 Operation , Operation 就会运行在主线程中,在子线程中执行 Operation , Operation 就运行在子线程中。它只有和 NSOperationQueue 联合使用的时候,才能发挥出价值。 NSOperationQueue 是 Operation 的管理者,它首先是一个队列,先来的任务先开始执行,后来的任务后开始执行,这些任务的执行是并发的, NSOperationQueue 负责为任务开辟线程以及关闭线程,有点类似于 cell 重用,用有限的线程执行任意数量的任务,同时可以设置最大并发数,控制程序的性能,不至于全部任务一起执行。 GCD 出现比 NSOperationQueue 要晚,是一套基于 C 函数的 API ,由于是 C 函数,所以性能比较高,使用灵活,安全,当然功能也强大。但是相对于 GCD 来讲, NSOperationQueue 对线程做了封装,使用比较简单,尤其是不用管理线程的开启和关闭。个人认为,如果仅仅是想要实现异步执行任务,首选 GCD ,如果要管理多个异步任务, NSoperationQueue 比较方便。如果要做更复杂的处理,比如前 5 个任务并发, 5 个任务执行完之后,需要串行执行 3 个任务,之后再并发执行若干任务,就需要使用 GCD 了。总的来说,特别简单的和非常复杂的多线程任务 GCD 比较适合,介于二者之间的用 NSOperationQueue 比较合适。 5. 写出在多线程情况下的一个单例。 答:一般情况下,在开发中我们所写的单例都是伪单例。即只是保证了在调用某一方法时,所产生的对象只有一个,但是没有考虑其他的影响其引用计数的方法。例如 retain 、 copy 等。为了保证线程安全,单例的写法如下所示: 方法一: static AccountManager *sharedAccountManagerInstance = nil; + (AccountManager *)sharedManager @synchronized (self) if (sharedAccountManagerInstance == nil) sharedAccountManagerInstance = [[AccountManager alloc] init]; return sharedAccountManagerInstance; 方法二: static AccountManager *sharedAccountManagerInstance = nil; + (AccountManager *)sharedManager static dispatch_once_t onceToken; dispatch_once(&onceToken, ^ sharedAccountManagerInstance = [[AccountManager alloc] init]; ); return sharedAccountManagerInstance;
10 ) OC 中创建线程的方法是什么?如果在主线程中执行代码,方法是什么 线程创建有三种方法 : 使用 NSThread 创建、使用 GCD 的 dispatch 、使用子类化的 NSOperation, 然后将其加入 NSOperationQueue; 在主线程执行代码 , 方法是 performSelectorOnMainThread, 如果想延时执行代码可以用 performSelector:onThread:withObject:waitUntilDone: 11) 线程和进程的区别和联系 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程 2 、 Autorelease 如果你什么都不考虑,在线程函数内调用 autorelease ,会出现错误 3 、子线程中描画窗口 多线程编程中普遍遵循一个原则,就是一切与 UI 相关的操作都有主线程做,子线程只负责事务,数据方面的处理。那么如果想在子线程中更新 UI 时怎么做呢?如果是在 windows 下,你会 PostMessage 一个描画更新的消息,在 iPhone 中,需要使用 performSelectorOnMainThread 委托主线程处理。 总结: 多线程能适当提高程序的执行效率,能适当提高资源利用率( CPU 、内存利用率),但是开启线程需要占用一定的内存空间(默认情况下,主线程占用 1M ,子线程占用 512KB ),如果开启大量的线程,会占用大量的内存空间,降低程序的性能,而且线程越多, CPU 在调度线程上的开销就越大,使用多线程程序设计更加复杂:比如线程之间的通信、多线程的数据共享 一个 iOS 程序运行后,默认会开启 1 条线程,称为“主线程”或“ UI 线程” 主线程的使用注意 : 别将比较耗时的操作放到主线程中。耗时操作会卡住主线程,严重影响 UI 的流畅度,给用户一种“卡”的坏体验 25. 线程是什么?进程是什么?二者有什么区别和联系? ( UI 第二十二讲 多线程编程) 线程是 CPU 独立运行和独立调度的基本单位(可以理解为一个进程中执行的代码片段),进程是资源分配的基本单位(进程是一块包含了某些资源的内存区域)。进程是线程的容器,真正完成代码执行的是线程,而进程则作为线程的执行环境。一个程序至少包含一个进程,一个进程至少包含一个线程,一个进程中的多个线程共享当前进程所拥有的资源。 26. 谈谈你对多线程开发的理解? ios 中有几种实现多线程的方法?( UI 第二十二讲 多线程编程) 好处: ①、使用线程可以把程序中占据时间长的任务放到后台去处理,如图片、视频的下载 ②、发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好 缺点: ①、大量的线程降低代码的可读性, ②、更多的线程需要更多的内存空间 ③、当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。 iOS 有三种多线程编程的技术: ①、 NSThread( 两种创建方式 ) [NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil]; NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil]; [myThread start]; ②、 NSOperationQueue NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init]; oprationQueue addOperationWithBlock:^ // 这个 block 语句块在子线程中执行
③、 Grand Central Dispatch (GCD) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ // 耗时的操作 dispatch_async(dispatch_get_main_queue(), ^ // 更新界面 ); );
PS: 不显示的创建线程的方法: 用 NSObject 的类方法 performSelectorInBackground:withObject: 创建一个线程: [Obj performSelectorInBackground:@selector(doSomething) withObject:nil]; 27. 线程同步和异步的区别? IOS 中如何实现多线程的同步? 同步:一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。 异步:同时去做两件或者多件事。比如边听歌边看报。 .runloop 和线程有什么关系? 总的说来, Run loop ,正如其名, loop 表示某种循环,和 run 放在一起就表示一直在运行着的循环。实际上, run loop 和线程是紧密相连的,可以这样说 run loop 是为了线程而生,没有线程,它就没有存在的必要。 Run loops 是线程的基础架构部分, Cocoa 和 CoreFundation 都提供了 run loop 对象方便配置和管理线程的 run loop (以下都以 Cocoa 为例)。每个线程,包括程序的主线程( main thread )都有与之相应的 run loop 对象。 runloop 和线程的关系:主线程的 run loop 默认是启动的。 iOS 的应用程序里面,程序启动后会有一个如下的 main() 函数 int main(int argc, char * argv[]) @autoreleasepool return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 重点是 UIApplicationMain() 函数,这个方法会为 main thread 设置一个 NSRunLoop 对象,这就解释了:为什么我们的应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。 对其它线程来说, run loop 默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动,如果线程只是去执行一个长时间的已确定的任务则不需要。 在任何一个 Cocoa 程序的线程中,都可以通过以下代码来获取到当前线程的 run loop 。 NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 51. GCD 的队列( dispatch_queue_t )分哪两种类型? 串行队列 Serial Dispatch Queue 并行队列 Concurrent Dispatch Queue 77. 你参与的 APP ,是如何处理多个服务的同步发起的? 使用 iOS 线程技术,创建并行队列来分别执行不同的任务。将不同的任务加入到子队列当中,任务执行后回到主线程当中刷新 UI 界面。 APP 界面一般都是根据产品需求和 UI 效果图来完成的,但是我们为了提高代码的复用性,会将视图的实现进行封装,然后在控制器当中进行加载调用 88.NSOperationQueue 有哪些使用方式? 一种在 iOS 中执行并发操作的方法,是使用 NSOperation 和 NSOperationQueue 类。在本教程中,你将学习如何使用它们!你会先创建一款不使用多线程的 app ,这样它会变得响应非常迟钝。然后改进程序,添加上并行操作–并且希望–可以提供一个交互响应更好的界面给用户! 另一种处理操作之间的依赖关系,如果操作直接有依赖关系,比如第二个操作必须等第一个操作结束后再执行。控制线程池中的线程数
3. NSThread 、 NSOperationQueue 以及 GCD 等多线程编程技术什么情况下使用? 1 )
以上是关于iOS开发中关于多线程的问题(NSOperationQueue,NSThread,GCD)的主要内容,如果未能解决你的问题,请参考以下文章