1.圖片選擇
隨著項(xiàng)目越來越大,圖片視頻選擇樣式越來越豐富秉氧,后期維護(hù)成本越來越高眷昆。項(xiàng)目初期所有的圖片視頻選擇放在一個 viewController看著還挺滿意,畢竟樣式單一汁咏,邏輯還算清晰亚斋。可是后面樣式越來越多攘滩,每次處理這部分代碼帅刊,都要花費(fèi)大半天時間來理解之前的邏輯。如果某一處邏輯考慮不全面漂问,就會引出crash厚掷,所以每次迭代又要調(diào)整這部分代碼時候,都是小心翼翼级解,嚴(yán)重影響項(xiàng)目進(jìn)度冒黑。
終于在一次迭代中, PM提出圖片選擇增加集合的概念勤哗,便于幾十屏照片的手機(jī)用戶快速找到需要的圖片抡爹。這次不能再往視頻圖片選擇里面添加代碼了,必須進(jìn)行重構(gòu)芒划。
重構(gòu)前一個MYImagePickerViewController里面碼完所有代碼冬竟。
重構(gòu)后框架如下:
MYImageAssetManager:單例,實(shí)現(xiàn)相冊集合數(shù)據(jù)源邏輯民逼。初始化時泵殴,更新相冊集合和相冊中照片和視頻的張數(shù),且監(jiān)聽系統(tǒng)相冊中資源更新拼苍。
MYMediaPickerViewController:父類笑诅,處理公共邏輯。1.請求訪問授權(quán) 疮鲫;2.通過對應(yīng)的PHAssetCollection獲取圖片視頻展示吆你;3.處理圖片上下滑動緩存邏輯。
MYVideoPickerViewController:子類俊犯,處理視頻選擇邏輯妇多。視頻最小長度,拍照入口等等燕侠。
MYImagePickerViewController:子類者祖,處理圖片選擇邏輯立莉。單選、多選七问,選折后裁剪等等桃序。
MYImageAlbumsViewController:頂部圖片選擇集切換。當(dāng)MYImagePickerViewController進(jìn)行圖片集切換時烂瘫,添加到父控制器MYImagePickerViewController上媒熊。
?MYImageVideoPickerViewController:發(fā)圖片發(fā)視頻切換,如上圖界面坟比。在子控制器芦鳍,MYImagePickerViewController和MYVideoPickerViewController之間切換。
下面分析MYImageAssetManager中部分代碼: ? ??
.h文件中的供外界訪問的屬性和方法? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?videoAssetCollection是MYVideoPickerViewController控制器的視頻集合葛账。 ? ? ? ? ? ? ? ?imageDefaultCollection是MYImagePickerViewController控制器默認(rèn)的圖片集合柠衅。 ? ? ? ? ?imageAssetCollections是MYImageAlbumsViewController控制器的圖片集數(shù)組。 ? ? ?
2.圖片選擇內(nèi)存占用高和界面上下滑動卡頓問題解決
圖片選擇多張大圖時籍琳,很容易引發(fā)界面卡頓菲宴,內(nèi)存占用率高,內(nèi)存不足閃退等問題趋急。
1>將獲取原圖方法- requestImageForAsset:targetSize:contentMode:options:resultHandler:修改為- requestImageDataForAsset:options:resultHandler:喝峦,在相同圖片大小上,內(nèi)存降低了很多呜达。后者直接返回二進(jìn)制數(shù)據(jù)谣蠢,不渲染。
2>獲取縮略圖用- requestImageForAsset:targetSize:contentMode:options:resultHandler:查近,獲取到UIImage后眉踱,可以用UIImageJPEGRepresentation轉(zhuǎn)換為NSData,傳遞圖像數(shù)據(jù)霜威。UIImageJPEGRepresentation轉(zhuǎn)化時候會有損耗谈喳,若項(xiàng)目中圖片數(shù)據(jù)傳遞的較多,超過其帶來的影響戈泼,所以可以忽略婿禽。
3>圖片在傳遞中用NSdata,若要用到UIImage矮冬,就這樣轉(zhuǎn)換:[UIImage imageWithData:imageData]谈宛。
4>界面卡頓問題次哈,可以將圖片進(jìn)行緩存胎署, 用PHAsset的localIdentifier作為緩存的key。
下面兩個方法分別用于獲取縮略圖和原圖窑滞。
3.圖片上傳壓縮琼牧,內(nèi)存再次高占用閃退
圖片壓縮上傳時恢筝,先獲取原圖,然后壓縮巨坊。如果原圖很大撬槽,壓縮時內(nèi)存再次高緊張。以下兩個步驟可以解決此問題趾撵。
1>異步隊(duì)列改為同步隊(duì)列
圖片壓縮之前放在異步隊(duì)列里面侄柔,當(dāng)幾十個圖片并發(fā)壓縮時,內(nèi)存突然一下飆升占调,當(dāng)所有圖片壓縮完成后暂题,內(nèi)存突然下降。就在突然飆升那一段究珊,如果手機(jī)內(nèi)存有限薪者,應(yīng)用就閃退了。之后改為同步隊(duì)列剿涮,內(nèi)存不會突然飆升言津,而是小幅上升依次處理每個壓縮。代碼如下:
這樣子解決了部分問題取试,但是依然有閃退存在悬槽。
2>以“自動釋放池”降低內(nèi)存峰值
autoreleasepool自動釋放池用于存放那些需要在稍后某個時刻釋放的對象,清空自動釋放池時瞬浓,系統(tǒng)會向其中的對象發(fā)送release消息陷谱。創(chuàng)建自動釋放池語法如下: ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @autoreleasepool{... ?} ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
花括號定義了自動釋放池的范圍,自動釋放池在左花括號處創(chuàng)建瑟蜈,并于右花括號處自動清空烟逊。位于自動釋放池范圍內(nèi)的對象,將在此范圍末尾處收到release消息铺根。
因此宪躯,在壓縮圖像時,可以通過autoreleasepool控制應(yīng)用的內(nèi)存峰值位迂,使其不致過高访雪。