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()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值