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

iOS多线程

2014-09-02 16:17 495 查看
在项目开发中,一个进程默认情况下,只有一个线程,也就是我们说的主线程。如果我们把所有的操作都在主线程中进行的话,很有可能会造成主线程堵塞,界面很卡,给用户很不好的体验效果。比较我们进入一个界面需要网络请求时,假如这个请求要十秒钟才能请求下来,如果这些都在主线程中进行的话,那这10秒钟我们就只能干看着手机,就连返回都不能,很显然,这样的应用时太坑爹了的。所以就需要我们手动来创建一个或者多个线程,来分担主线程的繁重的任务。

iOS现在创建线程,多线程操作的方式一共有三种:NSThread、NSOperation、GCD。废话不多说,进入正题。下面就是这三种线程一些简单的介绍。

一 NSThread方式创建线程

两种方式创建:

1.[NSThreaddetachNewThreadSelector:@selector(doSomething2:) toTarget:self withObject:@”传的参数”];

2.NSThread *myThread =[[NSThread alloc] initWithTarget:self selector:@selector(doSomething2:)object:@”参数”];

[myThread start];

//只有start的之后,线程才会正式启动。

 

NSThread方式进行多线程操作时,多个线程时必须上锁NSLock,在一个线程完成操作后解锁[theLock unlock];
通过NSCondition的signal方法,发送信号的方式,在这个线程中唤醒另外一个线程的等待

二 NSOperationQueue和NSOperation

通过NSOperationQueue建立一个线程管理器,建立过程:

 建立NSOperationQueue对象→建立NSOperation对象→将NSOperation对象加入到队列中→release掉NSOperation对象(非ARC下)
 

  NSOperation对象通过NSInvocationOperation类建立,是NSOperation的子类

  NSOperationQueue通过setMaxConcurrentOperationCount方法设定队列中线程的个数

 

创建方法:

NSOperationQueue *queue= [NSOperationQueue new];

NSInvocationOperation*operation = [[NSInvocationOperation alloc] initWithTarget:selfselector:@selector(doSomething:) object:@”传的参数是个字符串”];

[queueaddOperation:operation];

 

//运行在另外一个线程

-  (void)doSomething:(NSString *)string{

NSLog(@”%@”,string);

}

三 GCD

GCD:Grand Central Dispatch  是Apple开发的一个多核编程的解决方法。和block一起使用,使用最方便。

#pragma mark -
系统方法的GCD
/*
  dispatch_async开启一个异步请求
  第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列
  dispatch_get_global_queue指定为全局队列
  第一个参数是分配事物处理程序的块队列优先级。
  #define DISPATCH_QUEUE_PRIORITY_HIGH     2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT  0
  #define DISPATCH_QUEUE_PRIORITY_LOW     (-2)
 */
- (void)GCDwaysOne{
    //后台执行
    dispatch_async(dispatch_get_global_queue(0,0),
^{
        //something
    });
    
    //主线程执行
dispatch_async(dispatch_get_main_queue(), ^{
        //something
    });
    
    //一次性执行
    staticdispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //something
    });
    
    //延迟1秒执行
    double delayOne =1.0;
    dispatch_time_t time =dispatch_time(DISPATCH_TIME_NOW, delayOne *NSEC_PER_SEC);
    dispatch_after(time,dispatch_get_main_queue(), ^{

    });
}

#pragma mark -
自定义dispatch_queue_t
- (void)GCDwaysTwo{
    //自定义的dispatch_queue_t
    dispatch_queue_t url_queue =dispatch_queue_create("something",NULL);
    dispatch_async(url_queue, ^{
        //something
    });
   //非arc下需要释放
    //dispatch_release(url_queue);
}

#pragma mark -
后台多线程并发
/*
  异步和并发的不同点:
  异步只是提供了一种多线程处理的概念,
  并发是更像是异步的一种大规模实现
  */
- (void)GCDwaysThree{
    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),
^{
        //汇总结果
    });
}

这里我对三种方式创建多线程也做了一下总结,关于他们各自的优缺点。

优点:

NSThread:相比其它两种方式更加轻量,使用简单。

NSOperation:不需要关心线程管理,数据同步的事情;

NSOperationQueue可以添加依赖,让一个线程在另一个完成后才执行,没有上锁解锁这些繁琐的操作;

(NSOperation是基于OC实现的,所以是面向对象的创建线程的技术,网络请求的时候第三方框架,AFNetworking就是直接用的NSOperation)

GCD:抽象度是最高的,使用也就越简单,是Apple最推荐使用,基于C语言的框架开发的。而且GCD使用时,会与block结合起来用,比较简便高效。并且GCD能够在“多核”上使用多线程。

缺点:

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

注:所有创建的子线程都不能对UI进行操作,需回到主线程。例:网络请求完成后需要刷新界面就必须回到主线程。

  最后附上源码:https://github.com/pjw540566709/Thread

希望可以帮助到你。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息