線程之間的通訊,線程通訊
我們在iOS開發中使用多線程一般使用這幾種,NSThread,GCD,NSOperation;我們多在自線程中進行資料載入或者下載的操作,所以總免不了將擷取到的資料發送到主線程進行顯示或者進行操作,下面就是我們經常使用基本的線程之間的通訊; 項目的準備工作: 1.建立一個Xcode項目,在storyboard中建立一個image View,並設定約束和image view控制項的大小,關聯到viewController的( @property (weak, nonatomic) IBOutlet UIImageView *imageview;)屬性; 2.在子線程下載的圖片,然後顯示到image view上; 第一種:NSThread
-(void)thread{ // 建立一個字串 NSString *str = @"http://www.xiami.com/images/collect/802/2/10023802_1330239346.jpg"; [self performSelectorInBackground:@selector(loadImage:) withObject:str];}-(void)loadImage:(NSString *)str{ NSURL *url = [NSURL URLWithString:str]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; NSLog(@"loadImage----->%@",[NSThread currentThread]); /** * 這個方法回到主線程並且執行 * @param updateUI: 執行更新ui的方法 */ [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];}-(void)updateUI:(UIImage *)image{ self.imageview.image = image; }
觸發thread方法,performSelectorInBackground:withObject: ---->方法開啟一個子線程,在子線程中執行 loadImage: 的方法,在loadImage中下載圖片,然後調用performSelectorOnMainThread:withObject;回到主線程,在updateUI中將下載好的圖片賦值給imageView;
第二種:GCD
//調用gcd
-(void)gcd{ NSString *str = @"http://www.xiami.com/images/collect/802/2/10023802_1330239346.jpg";
//在下面這個block使用self會形成循環參考,使用__weak修飾weakSelf,可以放置循環參考; //控制器對block有一個強引用,如果在block中使用self的話,block也對控制器有一個強引用; __weak typeof(self) weakSelf = self; /** * 開啟一個非同步任務, * 擷取一個全域隊列,在全域隊列中下載圖片 * 開啟一個非同步任務,在這個非同步任務中擷取一個主隊列,在主隊列中更新ui; */ dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSURL *url = [NSURL URLWithString:str]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; dispatch_async(dispatch_get_main_queue(), ^{ weakSelf.imageview.image = image; }); });}
這個例子使用了兩個簡單的非同步工作群組合全域隊列和主隊列,進行下載操作和更新ui的操作; 第三種:NSoperation 建立繼承 NSOperation的檔案,DownLoadOperation.h
// DownLoadOperation.h// 線程之間的通訊//// Created by 兩好三壞 on 16/2/21.// Copyright © 2016年 qinakun. All rights reserved.//#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>typedef void(^FinishBlock)(UIImage *image);@interface DownLoadOperation : NSOperation//圖片地址@property(nonatomic,copy) NSString *imageUrl;@property(nonatomic,copy) FinishBlock finishBlock;@end
DownLoadOperation.m
//// DownLoadOperation.m// 線程之間的通訊//// Created by 兩好三壞 on 16/2/21.// Copyright © 2016年 qinakun. All rights reserved.//#import "DownLoadOperation.h"@implementation DownLoadOperation-(void)main{ @autoreleasepool { //1.1.拿著imageURLString去網路上下載 NSURL *url = [NSURL URLWithString:self.imageUrl]; //1.2.去網路上載入圖片 NSData *imageData = [NSData dataWithContentsOfURL:url]; //1.3.將我們從網路上擷取到的圖片的二進位,轉成UIImage UIImage *image = [UIImage imageWithData:imageData]; if (self.finishBlock) { self.finishBlock(image); } }}@end
在控制器中的代碼如下
-(void)operation{ DownLoadOperation *operation = [DownLoadOperation new]; operation.imageUrl = @"http://www.xiami.com/images/collect/802/2/10023802_1330239346.jpg"; // 使用block, operation.finishBlock = ^(UIImage *image){ __weak typeof(self) weakSelf = self; [[NSOperationQueue mainQueue] addOperationWithBlock:^{ weakSelf.imageview.image = image; }]; };}