)
移動開發(fā)前端【免費下載鏈接】JASONETTE-iOS Native App over HTTP, on iOS項目地址https://gitcode.com/gh_mirrors/ja/JASONETTE-iOS點擊查看免費下載導讀本文以 JASONETTE-iOS 倉庫中隨包引入的 SDWebImage版本 3.8.1官方文檔為骨架結合倉庫源碼中的真實調用點系統(tǒng)講解這套 iOS 圖片加載框架的核心能力與集成方式從UIImageViewWebCache的一行式異步加載到SDWebImageManager的下載/緩存調度再到SDImageCache的內存與磁盤兩級緩存、SDWebImageDownloader的獨立下載器以及 CocoaPods/Carthage/手動三種安裝路徑。讀完本文你將掌握在 iOS 應用中安全、高效地加載并緩存網絡圖片的完整實戰(zhàn)方案并能看懂 JASONETTE-iOS 中所有圖片相關組件導航圖標、背景圖、列表縮略圖、音頻封面等的底層實現(xiàn)。SDWebImage 是什么為 UIImageView 而生的遠程圖片加載庫SDWebImage 是一個 Objective-C 庫核心是給UIImageView提供一個 category使其直接支持加載來自網絡的遠程圖片同時提供一系列配套能力。官方文檔app/Pods/SDWebImage/README.md明確列出的功能包括為 Cocoa Touch 框架增加UIImageView分類集成 Web 圖片加載與緩存管理異步圖片下載器異步的內存 磁盤兩級緩存并帶自動緩存過期處理動畫 GIF 支持WebP 格式支持后臺圖片解壓保證同一 URL 不會被重復下載保證無效bogusURL 不會被反復重試保證主線程永不被阻塞基于 GCD 與 ARCArm64 架構支持。其中“同一 URL 不重復下載”與“無效 URL 不反復重試”兩個保證可以在 SDWebImageManager.m 的downloadImageWithURL:options:progress:completed:實現(xiàn)中看到框架內部維護failedURLs集合一旦某 URL 下載失敗即被加入黑名單后續(xù)請求除非顯式傳入SDWebImageRetryFailed選項否則直接返回緩存不存在的錯誤這就是“bogus URLs wont be retried again and again”的源碼依據。版本與系統(tǒng)兼容性README 明確指出3.8 版本需要 iOS 7 或更高版本因為使用了 NSURLSession3.0 至 3.7 需要 iOS 5.1.1如需支持 iOS 5.0 以下只能回退到最后的 2.0 兼容分支。當前倉庫實際鎖定版本為 3.8.1見 app/Podfile 的pod SDWebImage, :git https://github.com/rs/SDWebImage.git, :tag 3.8.1以及 app/Podfile.lock 中記錄的SDWebImage (3.8.1)且 JASONETTE-iOS 的 Podfile 聲明的部署平臺為platform :ios, 8.0并啟用了use_frameworks!完全滿足 3.8 的 iOS 7 前提。SDWebImage 在 JASONETTE-iOS 中的真實落地場景在深入 API 之前先看這個倉庫里 SDWebImage 的實際使用面——這是本文檔主題在當前項目中最直接的印證。通過搜索SDWebImageManager、sd_setImageWithURL:等符號可以確認以下調用點JasonImageComponent.m通過[SDWebImageManager sharedManager].imageDownloader拿到全局下載器為圖片請求動態(tài)設置 HTTP Header來自 Jasonette 的 session 配置與 JSON 中聲明的header再調用sd_setImageWithURL:placeholderImage:completed:加載遠程圖片本地file://圖片則用[UIImage sd_animatedGIFWithData:]處理動畫 GIF。Jason.m導航欄左右菜單的圖片按鈕直接使用SDWebImageManager sharedManager的downloadImageWithURL:options:progress:completed:下載并在主線程回調中設置按鈕圖片。JasonAudioAction.m音頻流播放時下載封面圖生成MPMediaItemArtwork寫入鎖屏播放信息中心。JasonViewController.m、JasonLayer.m、JasonHorizontalSection.m單元格背景圖、layer 背景圖等均通過sd_setImageWithURL:異步加載。Jason.h、JasonImageComponent.h、JasonViewController.h、JasonAudioAction.h、JasonUtilAction.h、JasonHorizontalSection.h 統(tǒng)一通過#import SDWebImage/UIImageViewWebCache.h引入頭文件。由此可見SDWebImage 是 JASONETTE-iOS 所有遠程圖片鏈路的統(tǒng)一底層本文后面的 API 講解也全部對應這些真實調用。核心用法一UIImageViewWebCache 分類與 UITableView最小接入示例官方推薦的最簡單用法是導入UIImageViewWebCache.h頭文件后在tableView:cellForRowAtIndexPath:中調用sd_setImageWithURL:placeholderImage:從異步下載到緩存管理全部自動完成#import SDWebImage/UIImageViewWebCache.h - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *MyIdentifier MyIdentifier; UITableViewCell *cell [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell nil) { cell [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; } // 使用 sd_setImageWithURL: 方法加載網絡圖片 [cell.imageView sd_setImageWithURL:[NSURL URLWithString:http://www.domain.com/path/to/image.jpg] placeholderImage:[UIImage imageNamed:placeholder.png]]; cell.textLabel.text My Text; return cell; }說明示例中的autorelease是早期 MRC 時代的寫法當前倉庫所有代碼均運行在 ARC 環(huán)境下實際工程中直接創(chuàng)建 cell 即可無需手動管理內存。完整方法族UIImageViewWebCache.h 中定義了從簡到繁的一整套方法可按需選擇方法說明sd_imageURL獲取當前 imageView 正在加載/已加載的圖片 URLsd_setImageWithURL:最簡形式僅指定 URL異步下載并緩存sd_setImageWithURL:placeholderImage:指定占位圖下載完成前顯示sd_setImageWithURL:placeholderImage:options:追加SDWebImageOptions行為選項sd_setImageWithURL:completed:帶完成回調SDWebImageCompletionBlocksd_setImageWithURL:placeholderImage:completed:占位圖 完成回調sd_setImageWithURL:placeholderImage:options:completed:選項 完成回調sd_setImageWithURL:placeholderImage:options:progress:completed:完整形態(tài)進度回調 完成回調sd_setImageWithPreviousCachedImageWithURL:...優(yōu)先展示上一次緩存圖片同時嘗試刷新sd_setAnimationImagesWithURLs:用一組 URL 做幀動畫循環(huán)sd_cancelCurrentImageLoad取消當前下載setShowActivityIndicatorView:/setIndicatorStyle:加載時顯示系統(tǒng)菊花指示器其中完成回調SDWebImageCompletionBlock的簽名為(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)——第三個參數cacheType用于判斷圖片來自網絡SDImageCacheTypeNone、磁盤緩存SDImageCacheTypeDisk還是內存緩存SDImageCacheTypeMemory枚舉定義見 SDImageCache.h。注意如果圖片請求在完成前被取消例如 cell 復用導致舊請求被新請求取代成功與失敗回調都不會被調用——這是官方文檔明確說明的行為也是 UITableView 快速滾動時避免錯亂的關鍵保證。核心用法二使用 blocks 感知進度與結果在下載進度與最終結果都需要感知的場景下使用帶 block 的重載方法。進度回調會在下載過程中反復觸發(fā)攜帶receivedSize與expectedSize完成回調則在成功或失敗時各觸發(fā)一次[cell.imageView sd_setImageWithURL:[NSURL URLWithString:http://www.domain.com/path/to/image.jpg] placeholderImage:[UIImage imageNamed:placeholder.png] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { // ... 完成后的處理代碼 }];該模式在 JASONETTE-iOS 中也被反復使用。以 JasonImageComponent.m 為例完成回調中把下載圖片的實際尺寸寫入JasonComponentFactory.imageLoaded供后續(xù)按比例推算高度使用若 JSON 樣式聲明了style.color還會用imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate配合setTintColor:將圖片染成指定顏色。核心用法三SDWebImageManager——下載器與緩存的調度中樞直接使用 ManagerSDWebImageManager是UIImageViewWebCache分類背后的核心類負責把異步下載器SDWebImageDownloader與圖片緩存SDImageCache串聯(lián)起來SDWebImageManager.h 中的定義。在非UIView場景例如純 Cocoa 環(huán)境、需要手動控制圖片用途的場景下可直接使用SDWebImageManager *manager [SDWebImageManager sharedManager]; [manager downloadImageWithURL:imageURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // 進度跟蹤代碼 } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (image) { // 使用圖片 } }];注意 Manager 版完成回調比分類版多一個finished參數當啟用SDWebImageProgressiveDownload漸進式下載時finished NO的回調會攜帶半成品圖片反復觸發(fā)最后一次下載完畢才以finished YES返回完整圖片。下載流程源碼解析在 SDWebImageManager.m 中可以看到完整調度邏輯參數防御URL 傳成 NSString 會被自動轉為 NSURL傳 NSNull 等非法對象則置為 nil防止崩潰黑名單檢查URL 為空或未指定SDWebImageRetryFailed且 URL 在failedURLs中時直接回調錯誤不發(fā)請求生成緩存 keycacheKeyForURL:默認返回url.absoluteString若設置了cacheKeyFilter則走過濾器先查緩存queryDiskCacheForKey:命中則直接回調緩存圖片未命中或帶SDWebImageRefreshCached時再發(fā)起下載把 Manager 選項逐位映射為SDWebImageDownloaderOptions下發(fā)給下載器。Manager 還提供cachedImageExistsForURL:/diskImageExistsForURL:同步與異步兩種版本、cacheKeyForURL:、saveImageToCache:forURL:、cancelAll、isRunning等輔助 API方便業(yè)務側自行探測緩存狀態(tài)。SDWebImageOptions 選項全解SDWebImageManager通過位掩碼SDWebImageOptions控制單次請求行為定義見 SDWebImageManager.h選項位行為SDWebImageRetryFailed1 0關閉 URL 黑名單允許對失敗 URL 重試SDWebImageLowPriority1 1下載延遲到 UI 交互結束后如滾動減速期再開始SDWebImageCacheMemoryOnly1 2禁止磁盤緩存僅寫內存緩存SDWebImageProgressiveDownload1 3漸進式下載邊下邊顯示類似瀏覽器SDWebImageRefreshCached1 4即使命中緩存也尊重 HTTP 緩存控制頭并嘗試刷新見下文“圖片刷新”SDWebImageContinueInBackground1 5App 退后臺后繼續(xù)下載iOS 4SDWebImageHandleCookies1 6請求攜帶NSHTTPCookieStore中的 CookieSDWebImageAllowInvalidSSLCertificates1 7允許不受信任的 SSL 證書僅測試用SDWebImageHighPriority1 8將請求提到隊列最前SDWebImageDelayPlaceholder1 9延遲加載占位圖直到圖片加載完成SDWebImageTransformAnimatedImage1 10對動畫圖也執(zhí)行變換代理方法SDWebImageAvoidAutoSetImage1 11不自動設置到 imageView交由業(yè)務在回調中手動設置核心用法四獨立使用異步下載器 SDWebImageDownloader如果不想要緩存只使用下載部分可以脫離 Manager 直接操作單例下載器SDWebImageDownloader.hSDWebImageDownloader *downloader [SDWebImageDownloader sharedDownloader]; [downloader downloadImageWithURL:imageURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // 進度跟蹤代碼 } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { if (image finished) { // 使用圖片 } }];下載器版完成回調額外返回原始NSData便于自行處理原始數據例如判斷格式。下載器的關鍵可配置屬性結合 SDWebImageDownloader.m 源碼確認默認值maxConcurrentDownloads最大并發(fā)下載數默認 6downloadTimeout請求超時秒數默認 15.0并通過NSURLSessionConfiguration.timeoutIntervalForRequest生效executionOrder執(zhí)行順序默認SDWebImageDownloaderFIFOExecutionOrder先進先出可選SDWebImageDownloaderLIFOExecutionOrder后進先出棧式headersFilter每次下載請求前對 Header 做統(tǒng)一改寫的 blocksetValue:forHTTPHeaderField:為所有下載請求追加固定 HTTP HeaderJASONETTE-iOS 正是用此 API 注入鑒權頭見 JasonImageComponent.murlCredential/username/password請求憑據shouldDecompressImages下載后是否后臺解壓默認 YESsetOperationClass:替換默認的SDWebImageDownloaderOperation實現(xiàn)類。下載器還會通過SDWebImageDownloadStartNotification/SDWebImageDownloadStopNotification發(fā)出開始/停止通知并支持setSuspended:掛起隊列與cancelAllDownloads取消全部任務。核心用法五獨立使用異步緩存 SDImageCacheSDImageCache維護一塊內存緩存和一塊可選的磁盤緩存磁盤寫入是異步的不會給 UI 增加額外延遲SDImageCache.h??蚣芴峁﹕haredImageCache單例也支持用自定義命名空間創(chuàng)建獨立實例從而隔離緩存域SDImageCache *imageCache [[SDImageCache alloc] initWithNamespace:myNamespace]; [imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) { // image 非 nil 表示緩存命中 }];查詢與寫入查詢用queryDiskCacheForKey:done:若返回 nil說明緩存未命中此時應由業(yè)務方負責生成并寫入圖片。緩存 key 是應用內唯一的圖片標識通常就是圖片的絕對 URL。默認情況下內存未命中會自動繼續(xù)查磁盤緩存若只想查內存用imageFromMemoryCacheForKey:同步方法。寫入用storeImage:forKey:默認同時寫入內存與磁盤磁盤異步若只想寫內存使用storeImage:forKey:toDisk:并將第三個參數傳負數。更精細的寫入接口storeImage:recalculateFromImage:imageData:forKey:toDisk:允許直接保存服務端原始imageData避免二次壓縮導致的畫質損失與 CPU 開銷。緩存策略與自動清理從 SDImageCache.m 的初始化實現(xiàn)可確認以下默認行為磁盤緩存目錄規(guī)則為com.hackemist.SDWebImageCache. 命名空間位于默認 Caches 目錄下maxCacheAge默認 7 天kDefaultCacheMaxCacheAge 60 * 60 * 24 * 7對應 README 中“自動緩存過期處理”的默認值磁盤清理通過cleanDisk系列方法刪除過期文件內存緩存基于AutoPurgeCacheNSCache 子類收到UIApplicationDidReceiveMemoryWarningNotification時自動clearMemoryApp 進入后臺或即將終止時自動執(zhí)行cleanDisk背景清理shouldDecompressImages默認 YES控制下載圖片是否后臺解壓——解壓能提升渲染性能但更耗內存若因內存過大崩潰可關閉還有maxMemoryCost、maxMemoryCountLimit、maxCacheSize等上限參數以及addReadOnlyCachePath:支持將預置圖片目錄作為只讀緩存路徑適合內置離線圖片包。清理類方法包括clearMemory清內存、clearDisk/clearDiskOnCompletion:清磁盤、cleanDisk/cleanDiskWithCompletionBlock:僅清過期、getSize/getDiskCount/calculateSizeWithCompletionBlock:統(tǒng)計占用。核心用法六緩存 key 過濾器某些場景下圖片 URL 帶有動態(tài)部分例如用于訪問控制的 query 參數直接用 URL 當緩存 key 會導致同一張圖反復緩存、緩存命中率下降。SDWebImageManager提供cacheKeyFilterblock輸入NSURL、輸出自定義的緩存 keyNSString。以下示例在 AppDelegate 中設置過濾器在生成緩存 key 前剔除 URL 的 query-string- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { SDWebImageManager.sharedManager.cacheKeyFilter ^(NSURL *url) { url [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; return [url absoluteString]; }; // 其他初始化代碼... return YES; }其生效位置在 SDWebImageManager.mcacheKeyForURL:優(yōu)先調用self.cacheKeyFilter(url)未設置時才回退為[url absoluteString]。常見問題與踩坑指南動態(tài)圖片尺寸導致 UITableViewCell 變形UITableView 會以第一次設置到 cell 上的圖片尺寸來決定 cell 高度。如果遠程圖片與占位圖尺寸不一致可能出現(xiàn)奇怪的拉伸/變形。官方給出的緩解思路是讓 cell 內的圖片保持固定寬度相關文章在 README 中以外部鏈接形式給出。JASONETTE-iOS 對這類問題的處理更徹底它在 JasonImageComponent.m 中根據已加載圖片的真實寬高比在布局階段自動補齊缺失的height或width從而保持 cell 尺寸穩(wěn)定。圖片刷新SDWebImageRefreshCachedSDWebImage 默認緩存策略非常激進忽略服務端返回的所有緩存控制頭對圖片不做時間限制地長期緩存。這意味著圖片 URL 必須是靜態(tài)的指向永不變化的資源若圖片內容發(fā)生變化URL 的對應部分也應同步變化。對于無法控制服務端 URL 的場景典型如 Facebook 頭像這類 URL 不變但內容更新的接口使用SDWebImageRefreshCached選項即可——代價是輕微的性能損失但會尊重 HTTP 緩存控制頭[imageView sd_setImageWithURL:[NSURL URLWithString:https://graph.facebook.com/olivier.poitrey/picture] placeholderImage:[UIImage imageNamed:avatar-placeholder.png] options:SDWebImageRefreshCached];該選項的源碼行為見 SDWebImageManager.m若命中緩存會先回調一次緩存圖片再發(fā)起網絡刷新最后以最終圖片回調一次完成回調觸發(fā)兩次同時SDWebImageRefreshCached會被映射為下載器層的SDWebImageDownloaderUseNSURLCache讓磁盤緩存交由 NSURLCache 處理。添加加載進度指示器README 指向了一個獨立的第三方分類UIActivityIndicator-for-SDWebImage。實際上當前版本已內置此能力setShowActivityIndicatorView:YES配合setIndicatorStyle:即可顯示系統(tǒng)菊花。JASONETTE-iOS 正是這樣用的JasonImageComponent.m 中設置灰色指示器。安裝方式詳解官方文檔提供了三種接入方式結合倉庫現(xiàn)狀分別說明。方式一CocoaPods當前倉庫采用的方式platform :ios, 7.0時寫入platform :ios, 7.0 pod SDWebImage, ~3.8若使用 Swift需添加use_frameworks!并把平臺提升到 iOS 8platform :ios, 8.0 use_frameworks!當前倉庫的 app/Podfile 正是如此平臺聲明為ios, 8.0、開啟use_frameworks!并將 SDWebImage 固定為 git 倉庫的 3.8.1 tag。若倉庫網絡不可用也可以直接在 app/Pods/SDWebImage 目錄中使用已集成的 3.8.1 完整源碼。Subspecs3.8 提供三個子模塊——Core默認含核心功能、MapKit、WebP。默認安裝只包含Core需要 WebP 時顯式聲明pod SDWebImage/WebP對應源碼中的條件編譯SDWebImageDownloader 僅在定義了SD_WEBP時才把Accept: image/webp,image/*;q0.8加入默認請求頭見 SDWebImageDownloader.m。方式二CarthageiOS 8在 Cartfile 中聲明github rs/SDWebImage集成后Swift 導入方式視安裝途徑而定經 CocoaPods 安裝用import SDWebImage手動安裝則import WebImageObjective-C 使用import WebImage;。方式三手動集成克隆倉庫獲取全部文件下載/解壓框架后在工程導航器中右鍵選擇 Add Files to Your Project選中SDWebImage.framework并勾選 Copy items into destination groups folder (if needed)在 target 的 Build Phases → Link Binary With Libraries 中添加ImageIO.framework漸進式下載功能依賴它在 Build Settings → Other Linker Flags 中加入-ObjC若-ObjC與擴展了可選庫的框架如 Parse、RestKit、opencv2發(fā)生編譯沖突改用-force_load SDWebImage.framework/Versions/Current/SDWebImage使用 CocoaPods 且存在上述沖突時改用-force_load $(TARGET_BUILD_DIR)/libPods.a并追加$(inherited)在需要使用的源文件中導入#import SDWebImage/UIImageViewWebCache.h完成上述步驟后工程即可正常編譯。官方路線圖未來的增強方向README 末尾列出了作者規(guī)劃的下一步改進用 LRU 內存緩存清理替代“收到內存警告即整體清空”的粗暴策略。從 SDImageCache.m 可以看到3.8.1 的內存緩存處理仍是“收到UIApplicationDidReceiveMemoryWarningNotification時調用clearMemory整體清空”因此該 Roadmap 項在本文檔所對應版本中尚未落地讀者如需 LRU 語義可關注后續(xù)版本或自行在AutoPurgeCache之上擴展。許可證SDWebImage 全部源碼以 MIT 許可證發(fā)布倉庫內對應文件為 app/Pods/SDWebImage/LICENSE。在 JASONETTE-iOS 中使用含app/Pods/SDWebImage/SDWebImage目錄下的全部實現(xiàn)即受此許可證約束。小結SDWebImage 3.8 用三個層次清晰的組件UIImageViewWebCache分類、SDWebImageManager調度器、SDImageCacheSDWebImageDownloader基礎設施解決了 iOS 遠程圖片加載的全部痛點異步不阻塞主線程、內存/磁盤兩級緩存、URL 去重與失敗黑名單、GIF/WebP 支持、后臺解壓與自動過期清理。在 JASONETTE-iOS 中它承擔著從列表縮略圖、導航菜單圖標、頁面背景到音頻封面的一切遠程圖片任務其倉庫內完整源碼與各 Jasonette 組件 中的調用點是學習這套框架最佳的本土化教材。贊分享移動開發(fā)前端【免費下載鏈接】JASONETTE-iOS Native App over HTTP, on iOS項目地址https://gitcode.com/gh_mirrors/ja/JASONETTE-iOS點擊查看免費下載相關推薦JASONETTE-iOS圖片加載與緩存SDWebImage在項目中的最佳實踐JASONETTE iOS圖片加載與緩存SDWebImage在項目中的最佳實踐 想要在iOS應用中實現(xiàn)快速、流暢的圖片加載體驗JASONETTE iOS項目移動開發(fā)前端SDWebImage 在 Delta 模擬器中的圖片加載實踐iOS 異步下載與多級緩存完全指南SDWebImage 在 Delta 模擬器中的圖片加載實踐iOS 異步下載與多級緩存完全指南 Delta 是一款面向非越獄 iOS 設備的全能經典游戲模擬器游戲開發(fā)解決iOS圖片加載痛點SDWebImage多緩存系統(tǒng)設計與實戰(zhàn)指南解決iOS圖片加載痛點SDWebImage多緩存系統(tǒng)設計與實戰(zhàn)指南 你是否還在為APP圖片加載速度慢、內存占用高而困擾作為iOS開發(fā)中最流行的圖片處理庫S移動開發(fā)圖像處理上一篇使用 Lightning Fabric 加速 DCGAN 人臉生成從原始 PyTorch 到零樣板代碼的分布式訓練遷移下一篇CANN/runtime查看Ascend RC日志創(chuàng)作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考