电竞比分网-中国电竞赛事及体育赛事平台

分享

iOS的多線程

 Han_Count 2016-06-20

進(jìn)程:內(nèi)存里的一個(gè)程序就是一個(gè)進(jìn)程,運(yùn)行起來的程序就是一個(gè)進(jìn)程,程序并不能單獨(dú)運(yùn)行,只有將程序裝載到內(nèi)存中,系統(tǒng)為它分配資源才能運(yùn)行,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空間內(nèi),而這種執(zhí)行的程序就稱之為進(jìn)程。程序和進(jìn)程的區(qū)別就在于:程序是指令的集合,它是進(jìn)程運(yùn)行的靜態(tài)描述文本;進(jìn)程是程序的一次執(zhí)行活動(dòng),屬于動(dòng)態(tài)概念。

線程:線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體,一個(gè)應(yīng)用至少有一個(gè)線程(主線程)(IOS中UI主線程)

iOS有三種多線程編程的技術(shù),分別是:
(一)NSThread
(二)Cocoa NSOperation
(三)GCD(全稱:Grand Central Dispatch)

這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡(jiǎn)單,也是Apple最推薦使用的。


NSThread

  • 優(yōu)點(diǎn):NSThread 比其他兩個(gè)輕量級(jí)
  • 缺點(diǎn):需要自己管理線程的生命周期,線程同步。線程同步對(duì)數(shù)據(jù)的加鎖會(huì)有一定的系統(tǒng)開銷
-(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的方式有兩種,一種是用定義好的兩個(gè)子類: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語言,提供了非常多強(qiáng)大的函數(shù)

  • GCD的優(yōu)勢(shì)

    • 蘋果公司為多核的并行運(yùn)算提出的解決方案
    • 自動(dòng)利用更多的CPU內(nèi)核(比如雙核、四核)
    • 自動(dòng)管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)、銷毀線程)
    • 程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼


dispatch_queue_t queue =dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        //1.獲取網(wǎng)址字符串
        NSString * urlString = @"http://www./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,我們之所以能夠看到某些時(shí)候更新了的效果,是因?yàn)樽泳€程結(jié)束,立刻回到了主線程中,主線程更新子線程里面要求的UI,由于子線程結(jié)束回到主線程的時(shí)間比較短,因此造成了一種誤解,以為是子線程更新了UI,實(shí)則是UI主線程自己做的

  2. 如果在子線程里面直接更新UI, 可能會(huì)造成兩種錯(cuò)誤
    a. UI的更新不及時(shí),必須等子線程結(jié)束了,主線程才會(huì)去更新UI
    b. 當(dāng)子線程還沒有結(jié)束,主線程中已經(jīng)將UI元素釋放,那么當(dāng)子線程結(jié)束了,回到主線程中,就會(huì)去繼續(xù)更新這個(gè)UI元素,可是UI已經(jīng)沒有了,造成內(nèi)存錯(cuò)誤

  3. 當(dāng)子線程執(zhí)行完畢,立刻返回到主線程,如果子線程有需要讓主線程做一定的事情,那么主線程會(huì)掛起其他的任務(wù),執(zhí)行這些事情

參考資料
關(guān)于iOS多線程,你看我就夠了
iOS開發(fā)多線程篇—GCD介紹
iOS多線程編程之Grand Central Dispatch(GCD)介紹和使用

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多