杨小麦OC之旅--多线程

本文已更新至:  

iOS多线程学习笔记


7th,Dec,2015

多线程
“iOS中多线程使用并不复杂,关键是如何控制好各个线程的执行顺序、处理好资源竞争问题。”--KenShinCui

1.NSThread

优点:NSThread 比其他两个 轻量
缺点:难控制线程顺序,线程总数也无法控制。需要自己管理 线程的生命周期线程同步。线程同步对 数据的加锁会有一定的系统开销.并且可能会导致大量的bug.创建和维护的成本很高(引入少量或中量长期存在的线程,执行重量级的操作,比如:网络操作,数据库操作)
tip
1)-currentThread// 获取当前线程  
2)sleepForTimeInterval // 让当前线程休眠
3)简单的多线程可以直接使用NSObject的扩展方法;
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg:在后台执行一个操作,本质就是重新创建一个线程执行当前方法。

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait:在指定的线程上执行一个方法,需要用户创建一个线程对象。

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait:在主线程上执行一个方法(前面已经使用过)。

// m1. 
// m2: 对象方法需要调用start 方法启动线程

// 在主线程中更新UI

多个线程按顺序启动,但实际执行 未必按顺序加载 照片:
1.因为线程启动后仅仅处于就绪状态,实际是否执行要由CPU根据当前状态调度。(虽然是按顺序启动,并不一定按顺序执行);
2. 每个线程执行时实际网络状况很可能不一致。
可以改变线程的优先级,线程优先级范围为0~1,值越大优先级越高,每个线程的优先级 默认为0.5
改变最后一张图片加载的优先级,这样可以提高它被优先加载的几率,但是它也未必就第一个加载。因为首先其他线程是先启动的,其次网络状况我们没办法修改
Demo:倒计时

2.NSOperation

优点:可控制线程总数与线程依赖关系,相比于GCD效率更高,并可监听线程完成状态。不需要关心线程管理,数据同步[信号量,互斥锁机制]的事情,可以把精力放在自己需要执行的操作上。
Cocoa operation 相关的类是 NSOperation ,NSOperationQueue(分派队列)。
NSOperation有两个常用子类用于创建线程操作:NSInvocationOperation和NSBlockOperation,两种方式本质没有区别,但是是后者使用Block形式进行代码组织,使用相对方便。
// -(void)loadImage


3.GCD

优点 :串行队列易于控制执行顺序,并发队列更高效
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。
时间以纳秒为单位
1)运行在主线程的Main queue,通过dispatch_get_main_queue获取。

2)并行队列【多个线程】global dispatch queue,通过dispatch_get_global_queue获取,由系统创建三个不同优先级的dispatch queue。并行队列的执行顺序与其加入队列的顺序相同。

3)串行队列【一个线程】(先进先执行)serial queues一般用于按顺序同步访问,可创建任意数量的串行队列,各个串行队列之间是并发的。
dispatch_retain和dispatch_release来控制变量的保留和释放,dispatch_susupend/dispatch_resume暂停 恢复

dispatch_async // 异步执行

分派屏障(dispatch barrier) 在并发队列内部创建一个同步点,运行时,即使有并发的条件和空闲的处理器核心,队列中的其它块也不能运行.没有屏障的可以看做共享(读取)锁.
@synchronize  管理多线程访问,会在参数上加一个互斥锁.  易用,但当竞争很少时成本很高
 // add on 1st,June,2016
Demo1:

Demo2:


4.锁机制

多个线程 并发执行,可能出现同时访问同一资源,造成资源抢夺。
解决方法:
1.NSLock同步锁.
可以通过tryLock方法,此方法会返回一个BOOL型的值,如果为YES说明获取锁成功,否则失败。另外还有一个lockBeforeData:方法指定在某个时间内获取锁,同样返回一个BOOL值,如果在这个时间内加锁成功则返回YES,失败则返回NO。--from cuijiangtao
demo:
_lock = [[NSLock alloc] init];
[_lock lock];
// 关键部分
[_lock unlock];
2. @synchronized代码块
demo: 
@synchronized(_myLockObj) {
 // 关键部分
}
3. GCD中dispatch_semaphore_t信号量
demo:
_semaphore=dispatch_semaphore_create(1);
dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
  //  关键部分
dispatch_semaphore_signal(_semaphore);//信号通知

小结

GCD 底层是C语言 iOS4.0推出。停止加入queueblock,要写复杂的代码。支持

dispatch_once; 延迟操作dispatch_after;调度组dispatch_group

NSOperation iOS2.0推出,推出GCD以后,对底层进行了重写,基于GCD进行封装。可以取消准备执行的操作,操作依赖,设置优先级,

设置最大操作并发数;




未完待续  今天要早点休息... 7th,Dec,2015
大体上对于多线程的总结相对完整了. 1st,June,2016
update on 29th,August,2016
看了代码整洁之道中第13章关于并发编程的描述,进一步整理下对于并发编程的理解。 ps: 博客中的图片为什么没了 . 11st,Nov,2016 还是默默用markdown吧。
参考资料:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值