首页 > 代码库 > 多线程
多线程
一个正在进行的应用程序 叫进程,一个进程 包括程序里的所有资源
线程是进程的一部分.进程是给线程提供资源的
任何一个程序至少有一个线程,那个程序叫主线程
系统会为线程分配 1兆的 栈空间
多线程是为了执行 并发
线程: 执行任务(代码)的单元
任务: 一个方法,代码段
1.什么是线程同步?
同步其实就是串行,线程2的执行依赖于线程1的结果.
2.如何实现同步:
建立一个NSOperationQueue,把它的线程最大值设为1
(方法: setMaxConcurrentOperationCount)
NSThread 线程类 isMainThread它的类方法,用来判断这个线程是不是主线程
凡前面是is的都是布尔值 ,打印的值是1(是组线程)或0
线程分两种: 脱离线程 和 非脱离线程
脱离线程: 执行完任务之后,自动销毁的线程
非脱离线程: 执行完任务之后,不会被销毁的线程,可以后续执行别的任务
主线程 是 非脱离线程
每一个线程都自带一个NSRunLoop对象,runloop默认是关闭的.一旦runloop开启,你的线程就会成为非脱离线程.runloop帮你轮询有没有新的任务分配到了这个线程里面
实现多线程的方式一:
使用 跟类 NSObject 中的 performSelecterXXX方法.
UI的刷新一定要再主线程里进行! 子线程刷新UI会异常,刷新不了,或者延迟刷新
多线程 背后执行 XX方法 .它解决了想立即执行的问题
如:[self performSelectorInBackground:@selector(aa) withObject:nil];
实现多线程的方式二(脱离线程):
使用 NSThread 类
二的第一个: 它解决了想立即执行的问题
创建一个线程, 并让线程执行 self 的aa方法
[NSThread detachNewThreadSelector:@selector(aa) toTarget:self withObject:nil];
[thread start]; 记得写开始执行(可以自己决定什么时候开始执行)
二的第二个: 它解决了想延迟执行的问题 ,就是在方法中调延迟方法,然后最外层的方法再被外界使用
NSThread *thread=[[NSThread alloc] initWithTarget:self selector:@selector(aa) object:nil];
[thread start]; 记得写开始执行(可以自己决定什么时候开始执行)
第三种实现多线程的方式: NSOperationQueue 操作队列 一个接口 调用的操作
NSInvocationOperation(程序调用操作) 是一个操作,在需要的时候开辟. 它是一个线程操作,为的是使用它来调一个可用的方法.所以在需要用到的时候添加即可. 然后再把它添加到NSOperationQueue对象上
NSInvocationOperation *op1=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(aa) object:nil]; NSBlockOperation *op2=[NSBlockOperation blockOperationWithBlock:^{ NSLog(@"这是一个block operation"); }]; //NSInvocationOperation 是一个操作,在需要的时候,开辟 NSOperationQueue *queue=[[NSOperationQueue alloc] init]; [queue setMaxConcurrentOperationCount:1];//线程最大数
[queue addOperation:op1]; //一旦把她加到NSOperationQueue时,需要start 即: [op1 start]
但现在只需要把操作放到队列里即可,不需要人为调用start,queue会根据op的排队情况,帮你调用start.会智能为op安排线程 [queue addOperation:op2];
第四种 实现多线程的方法是GCD
如果一个任务(方法)在子线程里面执行,我们需要在任务里面加自动释放池
原因: 因为,线程与线程之间 相互独立的.但是资源是共享的,共享 堆空间.如果子线程里开辟了空间,没有释放.其他线程也无法使用这块以及开辟的空间.
尤其是当子线程里大量使用便利构造器的时候,会导致很多堆空间无法回收内存
所有的autorelease只有遇到自动释放池的时候才会释放,所以任何子线程都要加自动释放池
线程 共享堆.栈不共享! 每个子线程默认的栈大小是512K.主线程栈大小是1M.栈主要是放 局部变量的,局部变量出了方法就会销毁,因此,尽管只有512K或者1M但是以及够用了.栈空间的大小 必须是4k的整数倍.
执行完子线程以后一定要回到主线程 ( 回到主线程 子线程通信)
方法:performSelectorOnMainThread: withObject: waitUntilDone:]; //waitUntilDone 等待结束 可以控制执行顺序
如下: 在
@autoreleasepool { 如果在子线程里面需要执行任务,一定要写到自动释放池里面 NSLog(@"+++%d",[NSThread isMainThread]); for (int i = 0; i < 1000; i++) { NSLog(@"%d",i); } //回到主线程 子线程通信.执行完子线程以后一定要回到主线程 [self performSelectorOnMainThread:@selector(bb) withObject:nil waitUntilDone:YES]; //waitUntilDone 等待结束 可以控制执行顺序 NSLog(@"子线程结束了"); } }
多线程