iOS 多线程入门

来源:互联网 发布:淘宝域名怎么填 编辑:程序博客网 时间:2024/04/30 11:17

一、iOS多线程

iOS多线程开发有三种方式:

 1. NSThread  2. NSOperation  3. GCD

iOS在每个进程启动后都会创建一个主线程,更新UI要在主线程上,所以也称为UI线程,是其他线程的父线程。

线程和进程的区:

线程(thread):用于指代独立执行的代码段。进程(process):用于指代一个正在运行的可执行程序,它可以包含多个线程。

二、NSThread

NSThreadhi轻量级的多线程开发,需要自己管理线程生命周期

创建线程主要实现方法:

/* 直接将操作添加到新线程中并执行,该方法无法拿到线程对象 */+ (void)detachNewThreadSelector:(SEL)selector /* 方法名 */                       toTarget:(id)target /* 调用对象 */                     withObject:(id)argument; /* 参数 *//* 创建线程对象,初始化线程任务,调用start方法启动线程 */- (instancetype)initWithTarget:(id)target /* 调用对象 */                      selector:(SEL)selector /* 方法名 */                        object:(id)argument;/* 参数 */

使用

/* 创建一个线程,初始化任务,创建线程并不会启动线程 */NSThread *thread = [[NSThread alloc] initWithTarget:self                                            selector:@selector(loadImage)                                              object:nil];[thread start];//启动线程/* 直接将操作添加到新线程并启动线程 */[NSThread detachNewThreadSelector:@selector(loadImage)                          toTarget:self                        withObject:nil];

下面是常用方法来控制线程:

/* 让线程休眠 */+ (void)sleepUntilDate:(NSDate *)date;/* 让当前执行线程休眠到某个时间 */+ (void)sleepForTimeInterval:(NSTimeInterval)time;/* 让当前执行线程休眠固定多少秒 *//* 终止线程 */+ (void)exit;/* 停止线程,注意在主线程中调用仅仅只是设置线程状态,不会立刻停止线程 */- (void)cancel;

三、NSOperation

NSOperation是个基类,我们直接使用的是它的子类: 1. NSInvocationOperation:调用方法SEL的方式执行线程可以使用它 2.  NSBlockOperation:调用Block的方式执行线程可以使用它

实例

//创建Invocation线程NSInvocationOperation *invocationOperation =         [[NSInvocationOperation alloc] initWithTarget:self                                              selector:@selector(loadImage)                                                object:nil];//注意如果直接调用start方法,则此操作会在主线程中调用// [invocationOperation start];//一般不会这么操作,而是添加到NSOperationQueue中//创建线程队列NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];operationQueue.maxConcurrentOperationCount = 5;//设置最大并发线程数//注意添加到线程队列后,队列里的线程就会开始执行[operationQueue addOperation:invocationOperation];//创建Block线程NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{    [self loadImage:[NSNumber numberWithInt:0]];}];//添加进线程队列[operationQueue addOperation:blockOperation];

四、 GCD

任务和队列
在 GCD 中,加入了两个非常重要的概念: 任务 和 队列。

 1. 任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。任务有两种执行方式: 同步执行 和 异步执行,他们之间的区别是 是否会创建新的线程。 2. 队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列。

串行队列和并发队列的创建:

/*创建一个队列 第一个参数:队列名称 第二个参数:队列类型,DISPATCH_QUEUE_SERIAL串行,DISPATCH_QUEUE_CONCURRENT并发 注意:GCD的queue不是指针类型*/dispatch_queue_t serialQueue = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);dispatch_queue_t concurrentQueue = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);/* 使用dispatch_get_global_queue() 方法取得一个全局的并发队列 */dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

队列的异步执行和同步执行:

//异步执行队列任务,第一个参数是队列,第二个参数是任务Blockdispatch_async(queue, ^{    [self loadImage:[NSNumber numberWithInt:i]];}); //同步执行队列任务,第一个参数是队列,第二个参数是任务Blockdispatch_sync(queue, ^{    [self loadImage:[NSNumber numberWithInt:i]];});

GCD的其他任务执行方法:

/* 重复执行某个任务,为了不阻塞线程可以使用dispatch_async()包装一下再执行 */dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));/* 单次执行一个任务,此方法中的任务只会执行一次,重复调用也没办法重复执行(单例模式中常用此方法)*/dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);/* 常用:延迟delayInSeconds秒后在队列queue执行block操作 */dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_queue_t queue, dispatch_block_t block);

五、线程同步

为什么需要线程同步?因为要解决多线程的资源抢夺的问题

//初始化锁对象NSLock *myLock = [[NSLock alloc] init];//加锁[myLock lock];//加锁后,下面的代码只能有一个线程进入执行if (_imageNames.count > 0) {    name = [_imageNames lastObject];    [_imageNames removeObject:name];}//使用完解锁[myLock unlock];
0 0
原创粉丝点击