1. 線程間通信
在1個進程中,線程往往不是孤立存在的,多個線程之間需要經常進行通信。
1.1 線程間通信的體現
(1)1個線程傳遞數據給另1個線程;
(2)在1個線程中執行完特定任務後,轉到另1個線程繼續執行任務。
1.2 線程間通信常用方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
1.3 線程間通信示例——圖片下載
示意圖:
代碼展示:
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
// [self download2];
//開啟一條子線程來下載圖片
[NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil];
}
-(void)downloadImage
{
//1.確定要下載網絡圖片的url地址,一個url唯一對應著網絡上的一個資源
NSURL *url = [NSURL URLWithString:@"http://p6.qhimg.com/t01d2954e2799c461ab.jpg"];
//2.根據url地址下載圖片數據到本地(二進制數據
NSData *data = [NSData dataWithContentsOfURL:url];
//3.把下載到本地的二進制數據轉換成圖片
UIImage *image = [UIImage imageWithData:data];
//4.回到主線程刷新UI
//4.1 第一種方式
// [self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:YES];
//4.2 第二種方式
// [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
//4.3 第三種方式
[self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
}
2. 線程安全
2.1 多線程的安全隱患
資源共享
(1)1塊資源可能會被多個線程共享,也就是多個線程可能會訪問同一塊資源;
(2)比如多個線程訪問同一個對象、同一個變量、同一個文件。
當多個線程訪問同一塊資源時,很容易引發數據錯亂和數據安全問題。
示意圖:
2.2 安全隱患解決 —— 互斥鎖
2.2.1 互斥鎖使用格式
@synchronized(鎖對象) { // 需要鎖定的代碼 }
注意:鎖定1份代碼只用1把鎖,用多把鎖是無效的
2.2.2 互斥鎖的優缺點
優點:能有效防止因多線程搶奪資源造成的數據安全問題;
缺點:需要消耗大量的CPU資源。
2.2.3 互斥鎖的使用前提
多條線程搶奪同一塊資源。
2.2.4 線程同步
(1)多條線程在同一條線上執行(按順序地執行任務);
(2)互斥鎖,就是使用了線程同步技術。
2.3 原子與非原子性
OC 在定義屬性時有 nonatomic 和 atomic 兩種選擇
atomic:原子屬性,為setter方法加鎖(默認就是atomic);
nonatomic:非原子屬性,不會為setter方法加鎖。
2.3.1 原子和非原子屬性的選擇
nonatomic 和 atomic 對比:
atomic:線程安全,需要消耗大量的資源
nonatomic:非線程安全,適合內存小的移動設備
2.3.2 IOS 開發建議
(1)所有屬性都聲明為nonatomic;
(2)盡量避免多線程搶奪同一塊資源;
(3)盡量將加鎖、資源搶奪的業務邏輯交給服務器端處理,減小移動客戶端的壓力。
【IOS 中的多線程網絡(二) 線程間通信與線程安全】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!