在 iOS App 中從網路加載圖片是高頻需求。若在主線程同步下載(如 dataWithContentsOfURL:),會阻塞 UI,導致介面凍結、滑動不流暢,嚴重影響用戶體驗。正確的做法是:在後台線程下載數據,回主線程更新 UI。
// ❌ 會卡死主線程
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:mainImageUrl]];
UIImage *image = [[UIImage alloc] initWithData:imageData];
// 直接更新 UI...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 1. 後台下載
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
UIImage *image = [UIImage imageWithData:data];
// 2. 回主線程更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
});
});
手寫 GCD 容易出現:Cell 重用導致圖片錯位、無快取機制、無併發控制、無佔位圖/失敗處理等問題。業界標準做法是接入成熟圖片加載框架:
// 僅一行代碼,自動處理:異步下載、記憶體/磁碟快取、Cell 重用安全、佔位圖、失敗重試
[self.imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl]
placeholderImage:[UIImage imageNamed:@"placeholder"]];
學習階段可手寫 GCD 理解線程模型;實際專案務必使用成熟庫,專注業務邏輯而非重複造輪子。若面試被問到原理,能說清「異步下載 + 主線程更新 + 快取策略 + 重用安全」即可。