為什么你的圖片要異步加載?
在仿寫天氣預報時,我們常常需要從網絡加載天氣圖標,例如顯示某個小時的天氣狀態圖標。這看似簡單的事情,如果處理不當,卻很容易造成界面卡頓,甚至影響整個 App 的用戶體驗。
錯誤做法:圖片同步加載會讓 UI 卡頓
假設你在展示天氣時這樣加載圖標:
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
self.weatherIcon.image = [UIImage imageWithData:data];
這段代碼有什么問題?它會直接在主線程中進行網絡請求和圖片解碼:
如果網絡慢,用戶界面會卡住甚至假死
如果在滑動列表(比如 TableView)中這么做,滾動會非常不流暢
圖片越大,問題越明顯
在 iOS 中,主線程負責所有界面渲染、用戶交互。一旦主線程被你“堵住”,就會引發體驗崩潰。
?正確做法:異步加載 + 主線程更新 UI
為了保證用戶界面流暢,我們應當把耗時操作放到后臺線程去執行,只在主線程中更新 UI。下面是一段優化后的代碼:
- (void)loadWeatherIcon:(NSString *)urlString {NSURL *url = [NSURL URLWithString:urlString];NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:urlcompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {if (data) {UIImage *image = [UIImage imageWithData:data];dispatch_async(dispatch_get_main_queue(), ^{self.weatherIcon.image = image;});}}];[task resume];
}
解釋:
dataTaskWithURL:?默認就在系統分配的后臺線程池中運行
dispatch_async(dispatch_get_main_queue(), ^{ ... })?是我們手動回到主線程更新 UI
整個過程對用戶而言是絲滑無感的異步體驗