| 現象 | 可能原因 | 排查步驟 |
|---|---|---|
| URL 加載不顯示 | 1. URL 為 nil/錯誤 2. 主線程同步阻塞 3. HTTPS/ATS 未配置 4. 圖片數據解碼失敗 5. ImageView 可見性/層級問題 | 檢查 URL → 改異步 → Info.plist ATS → 嘗試 SDWebImage → bringSubviewToFront |
| 本地圖片不顯示 | 1. 圖片名稱/擴展名錯誤 2. 圖片未加入 Target/Build Phases 3. Asset Catalog 配置錯誤 4. ImageView frame 為零/隱藏 5. 被其他 View 遮蓋 | 檢查拼寫 → Build Phases → Assets.xcassets → frame 檢查 → 層級調整 |
// 原代碼問題點:
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
// 1. 同步阻塞主線程 (嚴禁)
// 2. 無錯誤處理 (imageData 可能為 nil)
// 3. 無佔位圖/失敗圖
pictureImageView.image = [UIImage imageWithData:imageData];
// 本地加載
pictureImageView.image = [UIImage imageNamed:@"starblue.png"];
// 1. 圖片名稱區分大小寫 (真機)
// 2. 未加入 Copy Bundle Resources
- (void)loadImageFromURL:(NSString *)urlString placeholder:(UIImage *)placeholder {
// 1. 設置佔位圖
self.pictureImageView.image = placeholder;
// 2. 異步下載
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:urlString]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error || !data) {
NSLog(@"下載失敗: %@", error);
return;
}
UIImage *image = [UIImage imageWithData:data];
if (!image) {
NSLog(@"數據解碼失敗");
return;
}
// 3. 主線程更新 UI
dispatch_async(dispatch_get_main_queue(), ^{
// 防止 Cell 復用導致圖片錯位 (可選: 記錄 url 比對)
self.pictureImageView.image = image;
});
}];
[task resume];
}
| 庫 | 特點 | 一鍵解決 |
|---|---|---|
| SDWebImage | OC 經典、緩存、佔位、進度、轉碼 | ✅ URL、本地、GIF、WebP |
| Kingfisher | Swift 純粹、鏈式 API、緩存策略豐富 | ✅ 現代 Swift 項目首選 |
| Nuke | 高性能、Swift Concurrency 支援、圖片處理管道 | ✅ 高性能場景 |
#import
[self.pictureImageView sd_setImageWithURL:[NSURL URLWithString:urlString]
placeholderImage:[UIImage imageNamed:@"placeholder"]
options:SDWebImageRetryFailed
progress:nil
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (error) NSLog(@"加載失敗: %@", error);
}];
原答案提到的關鍵點:
[self.view bringSubviewToFront:self.pictureImageView];
確保 ImageView 不被其他透明/半透明 View 遮蓋。調試時可在 View Debugger (Xcode -> Debug View Hierarchy) 中檢查層級關係。
NSAppTransportSecurity
NSAllowsArbitraryLoads
<-- 允許 HTTP (不推薦生產)
NSExceptionDomains
yourdomain.com
NSExceptionAllowsInsecureHTTPLoads
hidden=NO, alpha=1, frame 非零, bringSubviewToFront。手寫異步加載僅適合學習,**生產項目請直接接入成熟庫**,避免重複造輪子並引入難以排查的 Bug。