ios多線程操作(三)—— 線程通訊

來源:互聯網
上載者:User

ios多線程操作(三)—— 線程通訊
一個進程中,線程並非單獨存在,往往需要與其他線程進行通訊以執行特定的任務。接下來就用一個簡單的例子來實現線程之間最簡單的通訊,並藉此探究一下UI控制項下得常見設定 需求:從網路上下載一張圖片在螢幕上顯示,圖片可以滾動,可以捏合縮放大小 項目開搞 建立一個新項目。 因為視圖有滾動的需求,所以需要添加一個UIScrollView以及一個顯示圖片的UIImageView

@interface ViewController () @property (nonatomic,strong) UIScrollView *scrollView;@property (weak,nonatomic) UIImageView *imgV;@end

在loadView方法裡面初始化UI控制項,將scrollView設為根視圖
- (void)loadView{    _scrollView = [[UIScrollView alloc] init];    self.view = _scrollView;    self.view.backgroundColor = [UIColor brownColor];    // 初始化UIImageView    UIImageView *imgV = [[UIImageView alloc] init];    [self.view addSubview:imgV];    self.imgV = imgV;}

設定scrollView的代理,圖片的縮放操作將由代理的方法來實現,在後台開啟一條線程執行下載圖片的耗時操作:
- (void)viewDidLoad {    [super viewDidLoad];    _scrollView.delegate = self;    // 最小縮放比例    _scrollView.minimumZoomScale = 0.5;    // 最大縮放比例    _scrollView.maximumZoomScale = 2.0;    // 在後台開啟一條線程執行下載圖片的耗時操作    [self performSelectorInBackground:@selector(downloadImage) withObject:nil];    // 列印所線上程    NSLog(@"viewDidLoad - %@",[NSThread currentThread]);}

將下載圖片抽取為一個方法downloadImage,該方法中實現了線程間的通訊 ———— 讓主線程更新UI,通知主線程區執行setImage:方法,通訊對象是從網路上下載的image圖片對象
- (void)downloadImage{    NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/4afbfbedab64034f06bd8359acc379310a551d78.jpg"];    NSData *data = [NSData dataWithContentsOfURL:url];    UIImage *image = [UIImage imageWithData:data];    // 更新UI都要在主線程執行    [self performSelectorOnMainThread:@selector(setImg:) withObject:image waitUntilDone:NO];    NSLog(@"downloadImage - %@",[NSThread currentThread]);}

在setImg:方法裡面讓圖片顯示
- (void)setImg:(UIImage *)img{    self.imgV.image = img;    // 設定UIImageView根據image自動調節frame的大小    [self.imgV sizeToFit];    // 設定scrollView滾動範圍    self.scrollView.contentSize = img.size;    NSLog(@"setImg - %@",[NSThread currentThread]);}

代理方法:
/** *  該方法返回需要縮放的view */- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{    return self.imgV;}


如此這般就簡單實現了線程間的通訊,程式會從網路上下載圖片顯示,控制台列印的結果如下

number = 1 代表在主線程上執行。 number = 2(只要number!=1)代表在子線程上執行。
耗時操作在後檯子線程執行,更新UI在主線程執行。 為何在後檯子線程執行,如果在主線程執行耗時操作,那麼該操作執行期間,主線程一直被佔用,使用者的操作就無法響應,這樣的後果可想而知。 為什麼更新UI要在主線程執行?在子線程中是不能進行UI 更新的,而可以更新的結果只是一個幻像:因為子線程代碼執行完畢了,又自動進入到了主線程,執行了子線程中的UI更新的函數棧,這中間的時間非常的短,就讓大家誤以為分線程可以更新UI。如果子線程一直在運行,則子線程中的UI更新的函數棧 主線程無法獲知,即無法更新。只有極少數的UI能更新,因為開闢線程時會擷取當前環境,如點擊某個按鈕,這個按鈕響應的方法是開闢一個子線程,在子線程中對該按鈕進行UI 更新是能及時的,如換標題,換背景圖,但這沒有任何意義。












相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.