| 
進程:內(nèi)存里的一個程序就是一個進程,運行起來的程序就是一個進程,程序并不能單獨運行,只有將程序裝載到內(nèi)存中,系統(tǒng)為它分配資源才能運行,每個進程均運行在其專用且受保護的內(nèi)存空間內(nèi),而這種執(zhí)行的程序就稱之為進程。程序和進程的區(qū)別就在于:程序是指令的集合,它是進程運行的靜態(tài)描述文本;進程是程序的一次執(zhí)行活動,屬于動態(tài)概念。 
線程:線程是指進程內(nèi)的一個執(zhí)行單元,也是進程內(nèi)的可調(diào)度實體,一個應用至少有一個線程(主線程)(IOS中UI主線程) iOS有三種多線程編程的技術,分別是:(一)NSThread
 (二)Cocoa NSOperation
 (三)GCD(全稱:Grand Central Dispatch)
 這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。 
 NSThread優(yōu)點:NSThread 比其他兩個輕量級缺點:需要自己管理線程的生命周期,線程同步。線程同步對數(shù)據(jù)的加鎖會有一定的系統(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的方式有兩種,一種是用定義好的兩個子類: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;  
}
 
 GCDdispatch_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,其他都不行
 
子線程沒有能力去更新主線程的UI,我們之所以能夠看到某些時候更新了的效果,是因為子線程結束,立刻回到了主線程中,主線程更新子線程里面要求的UI,由于子線程結束回到主線程的時間比較短,因此造成了一種誤解,以為是子線程更新了UI,實則是UI主線程自己做的
如果在子線程里面直接更新UI, 可能會造成兩種錯誤a. UI的更新不及時,必須等子線程結束了,主線程才會去更新UI
 b. 當子線程還沒有結束,主線程中已經(jīng)將UI元素釋放,那么當子線程結束了,回到主線程中,就會去繼續(xù)更新這個UI元素,可是UI已經(jīng)沒有了,造成內(nèi)存錯誤
當子線程執(zhí)行完畢,立刻返回到主線程,如果子線程有需要讓主線程做一定的事情,那么主線程會掛起其他的任務,執(zhí)行這些事情
 參考資料關于iOS多線程,你看我就夠了
 iOS開發(fā)多線程篇—GCD介紹
 iOS多線程編程之Grand Central Dispatch(GCD)介紹和使用
 |