在iOS里關于UIKit的操作都是放在主線程完域,因此如果主線程被阻塞住了,你的UI可能無法及時響應事件膘盖,給人一種卡頓的感覺转锈。大多數(shù)阻塞主線程的情況是在主線程做IO操作盘寡,比如文件的讀寫,包含數(shù)據(jù)庫撮慨、圖片竿痰、json文本或者log日志等脆粥,盡量將這些操作放放到子線程,或者在后臺建立對應的dispatch queue來做這些操作影涉。
前面提到對磁盤緩存的計算與清理变隔,可能要計算大量文件大小,可視為一個耗時操作蟹倾,我們應該開啟一條子線程匣缘,把遍歷過程放在子線程中執(zhí)行。
這時候便會發(fā)現(xiàn)一個問題鲜棠,因為在子線程中執(zhí)行肌厨,無法直接使用返回值,不能把遍歷結(jié)果傳給計算字符串方法計算回傳豁陆,所以在這里我們要用到block來進行傳值柑爸,方便方法間的傳值以及把計算轉(zhuǎn)化結(jié)果回調(diào)給方法調(diào)用者。
有些朋友可能對block的回傳順序和執(zhí)行順序不太了解盒音,所以這里詳細地解釋一下表鳍。這為了方便理解,這里把遍歷文件大小的方法(下稱: A方法(getDirectorySize))和轉(zhuǎn)化成字符串大小方法(下稱:B方法 (directorySizeString))簡單賦個標識里逆。
當外界需要求緩存文件大小并拿到數(shù)據(jù)展示時进胯,便可以調(diào)用B方法(directorySizeString),因為用戶調(diào)用該方法是為了獲取緩存文件大小字符串數(shù)據(jù)原押,所以block需要返回值,在該方法結(jié)束后回傳字符串數(shù)據(jù)給用戶偎血。而B(directorySizeString)方法需要把文件大小轉(zhuǎn)化成字符串數(shù)據(jù)诸衔,那它調(diào)用A方法(getDirectorySize)方法時需要拿到A中計算好的文件大小數(shù)值,所以A方法中的block也需要返回值颇玷,在方法調(diào)用結(jié)束后回傳int類型數(shù)據(jù)給B方法計算笨农。
所以整個方法的執(zhí)行流程如下:外界調(diào)用B方法 =》 B方法(調(diào)用A方法) =》 A方法 =》 A方法(結(jié)束后)A中的block(在block中把數(shù)據(jù)回傳給B) =》 B方法中的block(在block中把數(shù)據(jù)回傳給方法調(diào)用者) =》 用戶調(diào)用B方法時block塊中的代碼。至此整個方法調(diào)用結(jié)束帖渠,不熟悉的朋友也可以直接打斷點觀察整個執(zhí)行過程谒亦,更加直觀。
耗時操作完成后空郊,后面的數(shù)據(jù)展示和刷新UI操作應該回到主線程執(zhí)行份招。
這里還做了容錯處理,避免自己或合作伙伴在使用時傳入錯誤信息帶來的不必要麻煩狞甚。整個緩存清理業(yè)務類的抽取和封裝便到此全部結(jié)束锁摔。