GeekBand~iOS~开发高级进阶~第三周
多线程--NSThread
main thread主线程
在一个运行的iOS应用中,处理UIKit对象的所有方法调用。
程序启动后,系统自动创建主线程。
主线程阻塞,UI就会失去响应。只能从主线程操作UI.
长时间、大量计算及阻塞I/O都应该另开线程。
NSThread的初始化
1.动态
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
// 初始化线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
// 设置线程的优先级(0.0 - 1.0,1.0最高级)
thread.threadPriority = 1;
// 开启线程
[thread start];
参数:
selector:线程执行的方法,最多只接收一个参数
target:selector消息发送的对象
argument:传给selector的唯一参数,也可以是nil
2.静态
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
// 调用完毕后,会马上创建并开启新线程
3.隐式
[self performSelectorInBackground:@selector(run) withObject:nil];
获取当前线程
[self performSelectorInBackground:@selector(run) withObject:nil];
获取主线程
NSThread *main = [NSThread mainThread];
暂停当前线程
// 暂停2s
[NSThread sleepForTimeInterval:2];
// 或者
NSDate *date = [NSDate dateWithTimeInterval:2 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:date];
线程间通信
1.在指定线程上执行操作
[self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];
2.在主线程上执行操作
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
3.在当前线程执行操作
[self performSelector:@selector(run) withObject:nil];
多线程--Runloop
NSRunLoop是IOS消息机制的处理模式 。
主要作用:控制NSRunLoop里面线程的执行和休眠,在有事情做的时候使当前NSRunLoop控制的线程工作,没有事情做让当前NSRunLoop的控制的线程休眠。
一直在循环检测,从线程start到线程end,检测inputsource(如点击,双击等操作)同步事件,检测timesource同步事件,检测到输入源会执行处理函数,首先会产生通知,corefunction向线程添加runloop observers来监听事件,意在监听事件发生时来做处理。
runloopmode是一个集合,包括监听:事件源,定时器,以及需通知的runloop observers 模式包括:
default模式:几乎包括所有输入源(除NSConnection)
NSDefaultRunLoopMode模式 mode模式:处理modal panels
connection模式:处理NSConnection事件,属于系统内部,用户基本不用
event tracking模式:如组件拖动输入源 UITrackingRunLoopModes 不处理定时事件
common modes模式:NSRunLoopCommonModes 这是一组可配置的通用模式。将input sources与该模式关联则同时也将input sources与该组中的其它模式进行了关联。
多线程--NSOperation
作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程。
NSOperation和NSOperationQueue实现多线程的具体步骤:
(1)先将需要执行的操作封装到一个NSOperation对象中
(2)然后将NSOperation对象添加到NSOperationQueue中
(3)系统会⾃动将NSOperationQueue中的NSOperation取出来
(4)将取出的NSOperation封装的操作放到⼀条新线程中执⾏
NSOperation是个抽象类,并不具备封装操作的能力,必须使⽤它的子类。
NSInvocationOperation:
NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
[operation start];
NSBlockOperation:
//创建
NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
}];
//添加
[operation addExecutionBlock:^{
}];
NSOperationQueue:
作⽤:NSOperation可以调⽤start⽅法来执⾏任务,但默认是同步执行的
NSOperationQueue * queue=[[NSOperationQueue alloc]init];
[queue addOperation:operation1];
[queue addOperationWithBlock:^{
}];
多线程--GCD
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。
dispatch queue分成以下三种:
1)运行在主线程的Main queue,通过dispatch_get_main_queue获取。
2)并行队列global dispatch queue,通过dispatch_get_global_queue获取,由系统创建三个不同优先级的dispatch queue。并行队列的执行顺序与其加入队列的顺序相同。
3)串行队列serial queues一般用于按顺序同步访问,可创建任意数量的串行队列,各个串行队列之间是并发的。
用法:
// 后台执行:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// something
});
// 主线程执行:
dispatch_async(dispatch_get_main_queue(), ^{
// something
});
// 一次性执行:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// code to be executed once
});
// 延迟2秒执行:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// code to be executed on the main queue after delay
});
// 自定义dispatch_queue_t
dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
dispatch_async(urls_queue, ^{
// your code
});
dispatch_release(urls_queue);
// 合并汇总结果
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程一
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行执行的线程二
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
// 汇总结果
});
加载网络图片出现的问题
NSURL *imgURL = [NSURL URLWithString:@"http://thumb.takefoto.cn/wp-content/uploads/2016/04/201604140840253233.jpg"];
错误描述:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app‘s Info.plist file.
在iOS9 beta中,苹果将原http协议改成了https协议,使用 TLS1.2 SSL加密请求数据。
解决方法:
在info.plist 加入key
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
如图:
图1