Run Loop
Run Loop提供了一种异步执行代码的机制,不能并行执行任务
在主队列中,Main Run Loop直接配合任务的执行,负责处理UI事件、计时器,以及其它内核相关事件
Run Loop的主要目的是保证程序执行的线程不会被系统终止
Run Loop的工作特点
当有事件发生时,Run Loop会根据具体的事件类型通知应用程序做出响应
当没有事件发生时,Run Loop会进入休眠状态,从而达到省电的目的
当事件再次发生时,Run Loop会被重新唤醒,处理事件
主线程和其他线程中的Run Loop
iOS程序的主线程默认已经配置好了Run Loop
其他线程默认情况下没有设置Run Loop
一般在开发中很少会主动创建RunLoop,而通常会把事件添加到RunLoop中
RunLoop示意图
UIApplication中的Run Loop
多线程中的循环引用
如果self对象持有操作对象的引用,同时操作对象当中又直接访问了self时,才会造成循环引用
单纯在操作对象中使用self不会造成循环引用
注意:此时不能使用(weakSelf)
多线程中的资源共享
并发编程中许多问题的根源就是在多线程中访问共享资源。资源可以是一个属性、一个对象、网络设备或者一个文件等
在多线程中任何一个共享的资源都可能是一个潜在的冲突点,必须精心设计以防止这种冲突的发生
共享资源小结
为了保证性能,atomic仅针对属性的setter方法做了保护
而争抢共享资源时,如果涉及到属性的getter方法,可以使用互斥锁@synchronized可以保证属性在多个线程之间的读写都是安全的
无论是atomic还是@synchronized,使用的代价都是高昂的
建议:多线程是并发执行多个任务提高效率的,如果可能,应该在线程中避免争抢共享资源
正是出于性能的考虑,UIKit中的绝大多数的类都不是线程安全的,因此,苹果公司要求:更新UI相关的操作,应该在主线程中执行
NSObject的多线程方法
开启后台执行任务的方法
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
在后台线程中通知主线程执行任务的方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
获取线程信息
[NSThread currentThread]
线程休眠
[NSThread sleepForTimeInterval:2.0f];
特点
使用简单,量级轻
不能控制线程的数量以及执行顺
NSObject的多线程方法注意事项
NSObject的多线程方法使用的是NSThread的多线程技术
而NSThread的多线程技术不会自动使用@autoreleasepool
在使用NSObject或NSThread的多线程技术时,如果涉及到对象分配,需要手动添加@autoreleasepool
自动释放池常见面试代码
for (int i = 0; i < 10; ++i) {
NSString *str = @”Hello World”;
str = [str stringByAppendingFormat:@” - %d”, i];
str = [str uppercaseString];
NSLog(@”%@”, str);
}
问:以上代码存在什么样的问题?如果循环的次数非常大时,应该如何修改?
应该在循环外定义NSString,然后加入到自动释放池中。