概要
? ? 學習SDWebImage后自己嘗試寫出的異步加載網絡圖片的庫。從開始到完工經歷大大小小的改版。
? 使用編程語言:Object-C。 ??
? 功能:異步加載網絡圖片資源(圖片、GIF)、加載本地GIF、漸進式下載圖片。
如何使用
? ? 導入"UIImageView+URLImage.h",調用- (void)loadURLImageWith:(NSString*)url placeImage:(UIImage*)placeImage方法。
? ? GitHub地址:https://github.com/zhangzecheng/URL-Image。 (歡迎大家下載提出寶貴建議,順便點贊)
? ? 目前只對UIImageView進行添加分類加載網絡圖片。若其他控件也需要異步加載網絡圖片,可模仿代碼中UIImageView的調用方法。
思路(貼圖為最新代碼)
? ? 一開始只是用NSData的dataWithContentsOfURL方法結合多線程,這樣做的直觀結果就是加載圖片過程中APP不卡,可以順暢的做其他操作。當另外的控件也需要加載這張圖片時,卻照樣需要重走下載的流程。因此衍生出了緩存+沙盒的緩存機制。
? ? 加載圖片的URL,先在緩存中查找是否下載過。沒有則去沙盒中查找。若沙盒里也沒有保存對應的圖片資源(圖片、GIF),則去下載隊列里找,避免重復下載。此時將加載圖片資源的回調(ZCImageCompletion)保存起來,再去判斷是否已在下載隊列中,沒有在開啟下載功能。
這三個公有方法便是整個異步加載的圖片資源,為方便使用,已經將其寫在一個方法里。
? ?最初的“緩存”使用的是字典,可當APP內存不足時無法自動釋放,由此使用NSCache替換。NSCache當APP內存警告時自動清除,這里不再贅述。
? ?網絡請求返回的data直接轉為UIImage即可顯示,保存到緩存、沙盒中;若是加載GIF,則需要用data去創建一個CGImageSourceRef,遍歷CGImageSourceRef通過CGImageSourceCreateImageAtIndex拿到每一個CGImageRef,生成對應的UIImage,調用[UIImage animatedImageWithImages:imagesArrM duration:duration]來生成可加載GIF的UIImage。
? ? 由此,基本功能基本完成。但有個無關緊要的問題,便是當要加載的圖片過大時,雖然可以使用占位圖在APP上顯示讓界面不會有太多的空白。可有些需求是想看到加載的過程。由此變引入漸進式加載圖片的功能。為了引入這個功能,對代碼進行重新設計,剔除了“多線程+dataWithContentsOfURL”模式,引入了NSURLSession的類,用其進行網絡圖片資源的加載,并用ZCImageSource這個類來代表圖片資源。
? ? 在NSURLSession的代理方法- (void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask ?didReceiveData:(NSData*)data中,我們能拿到每次返回的數據,并將其拼接到之前已下載的data中,每次拿到data就將data轉為UIImage,這就是漸進式加載圖片的思路。