您的位置:首页 > 移动开发 > IOS开发

iOS开发之多线程

2016-03-31 18:32 381 查看
iOS中多线程的实现方式有NSThread、NSOperation和GCD(全称:Grand
Central Dispatch)。

1.NSThread:

优点:NSThread 比其他两个轻量级

缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销

有两种初始化方式

第一种先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息

//NSThread * thread= [[NSThread alloc]initWithTarget:selfselector:@selector(calculate) object:nil];

//// 开启子线程

//[threadstart];

第二种直接创建线程并且开始运行线程

[NSThread detachNewThreadSelector:@selector(calculate)toTarget:selfwithObject:nil];

在子线程中执行

-(void)calculate

{

// 在子线程里面执行的事件创建对象时可能会用到便利构造器,这时占用的内存释放不掉,所以和主线程一样在外面加一个自动释放池

@autoreleasepool {

NSBlockOperation *operation = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"%d",[NSThreadisMainThread]);

}];

[operation start];

int a=0;

for(int i
=1; i <= 355;i
++){

[selfperformSelectorOnMainThread:@selector(test:)withObject:[NSStringstringWithFormat:@"%d",a]waitUntilDone:YES];

a +=i;

}

}

}

2.NSOperation

使用 NSOperation的方式有两种,

一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。

另一种是继承NSOperation

NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。相当与java 中Runnalbe的Run方法。然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。

NSBlockOperation初始化方式

NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{

// NSLog(@"该吃饭了(⊙o⊙)哦");

//}];

//

//[queue addOperation:block];

最大并发数.所谓的最大并发数指的是同时执行的任务个数。如果最大并发数设置为1,可以实现多线程下的线程同步

// queue.maxConcurrentOperationCount = 1;
3.GCD

GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。

dispatch queue分为下面三种:

Serial

又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。

Concurrent

又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。

Main dispatch queue

它是全局可用的serial queue,它是在应用程序主线程上执行任务的。
下面来看gcd的使用
//
串行队列

dispatch_queue_t myQueue =dispatch_queue_create("com.baidu.myQueue",DISPATCH_QUEUE_SERIAL);

dispatch_async(myQueue, ^{

NSLog(@"%d",[NSThreadisMainThread]);

});//全局队列

dispatch_queue_t global
=dispatch_get_global_queue(0,0);

dispatch_async(global, ^{

NSLog(@"%d,dddd",[NSThreadisMainThread]);

});
1.为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0), ^{
//
耗时的操作
dispatch_async(dispatch_get_main_queue(),
^{
//
更新界面
});
});


2、dispatch_group_async的使用

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。

dispatch_queue_t
queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t
group = dispatch_group_create();
dispatch_group_async(group,
queue, ^{
[NSThread
sleepForTimeInterval:1];
NSLog(@"group1");
});
dispatch_group_async(group,
queue, ^{
[NSThread
sleepForTimeInterval:2];
NSLog(@"group2");
});
dispatch_group_async(group,
queue, ^{
[NSThread
sleepForTimeInterval:3];
NSLog(@"group3");
});
dispatch_group_notify(group,
dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
});


3、dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行




dispatch_queue_t
queue = dispatch_queue_create("com.baidu.myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue,
^{
[NSThread
sleepForTimeInterval:2];
NSLog(@"1");
});
dispatch_async(queue,
^{
[NSThread
sleepForTimeInterval:4];
NSLog(@"2");
});
dispatch_barrier_async(queue,
^{
NSLog(@"**");
[NSThread
sleepForTimeInterval:4];


});
dispatch_async(queue,
^{
[NSThread
sleepForTimeInterval:1];
NSLog(@"3");
});


4、dispatch_after

// 延迟多少秒之后执行任务

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(),
^{

NSLog(@"0000");

});
5、dispatch_once

只执行一次,单例的创建可以使用这个方法

static dispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

NSLog(@"1111");

});
6、 dispatch_apply

执行多次
NSArray * array=@[@1,@2,@3];
dispatch_apply(array.count,dispatch_get_global_queue(0,0),
^(size_t i){
NSLog(@"%zu%@",i,array[i]);
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: