iOS-多线程

文/Mustard_iOS(简书作者)
原文链接:http://www.jianshu.com/p/4062d97ee2e4
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

进程:内存里的一个程序就是一个进程,运行起来的程序就是一个进程,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,每个进程均运行在其专用且受保护的内存空间内,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。

线程:线程是指进程内的一个执行单元,也是进程内的可调度实体,一个应用至少有一个线程(主线程)(IOS中UI主线程)

iOS有三种多线程编程的技术,分别是:
(一)NSThread
(二)Cocoa NSOperation
(三)GCD(全称:Grand Central Dispatch)

这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。


NSThread
  • 优点:NSThread 比其他两个轻量级
  • 缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销
-(void)downloadImage:(NSString *) url{  
    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];  
    UIImage *image = [[UIImage alloc] initWithData:data];  
    if(image == nil){  
    } else{  
         [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];  
    }  
}  

-(void)updateUI:(UIImage*) image{  
    self.imageView.image = image;  
}  

- (void)viewDidLoad  {  
     [super viewDidLoad];  
   // [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];  
     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:kURL];  
     [thread start];  
}

NSOperation

使用 NSOperation的方式有两种,一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。另一种是继承NSOperation。

- (void)viewDidLoad{  
    [super viewDidLoad];  
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self  selector:@selector(downloadImage:)   object:kURL];  
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];  
    [queue addOperation:operation];   
}  

-(void)downloadImage:(NSString *)url{    
    NSURL *nsUrl = [NSURL URLWithString:url];  
    NSData *data = [[NSData alloc] initWithContentsOfURL:nsUrl];  
    UIImage * image = [[UIImage alloc] initWithData:data];  
    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];  
}  

-(void)updateUI:(UIImage*) image{  
    self.imageView.image = image;  
}

GCD
  • 什么是GCD?
    全称是Grand Central Dispatch,纯C语言,提供了非常多强大的函数

  • GCD的优势

    • 苹果公司为多核的并行运算提出的解决方案
    • 自动利用更多的CPU内核(比如双核、四核)
    • 自动管理线程的生命周期(创建线程、调度任务、销毁线程)
    • 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码


dispatch_queue_t queue =dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        //1.获取网址字符串
        NSString * urlString = @"http://www.bz55.com/uploads/allimg/121230/1-121230094954.jpg";
        //2.NSString->NSURL
        NSURL * url = [NSURL URLWithString:urlString];
        //3.同步下载
        NSData * data = [NSData dataWithContentsOfURL:url];
        UIImage * image = [UIImage imageWithData:data];
        dispatch_sync(dispatch_get_main_queue(), ^{
            self.view.backgroundColor = [UIColor colorWithPatternImage:image];
        });
    });

P.S.
子线程里面不能更行主线程的UI
只有主线程能够更新UI,其他都不行

  1. 子线程没有能力去更新主线程的UI,我们之所以能够看到某些时候更新了的效果,是因为子线程结束,立刻回到了主线程中,主线程更新子线程里面要求的UI,由于子线程结束回到主线程的时间比较短,因此造成了一种误解,以为是子线程更新了UI,实则是UI主线程自己做的

  2. 如果在子线程里面直接更新UI, 可能会造成两种错误
    a. UI的更新不及时,必须等子线程结束了,主线程才会去更新UI
    b. 当子线程还没有结束,主线程中已经将UI元素释放,那么当子线程结束了,回到主线程中,就会去继续更新这个UI元素,可是UI已经没有了,造成内存错误

  3. 当子线程执行完毕,立刻返回到主线程,如果子线程有需要让主线程做一定的事情,那么主线程会挂起其他的任务,执行这些事情


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值