本文由iOS開發網站51ios.net轉載自裡脊串的開發隨筆,裡脊串的網站是http://adad184.com/
一般項目進行都尾聲的時候 就要開始清理項目了 一般包括
- 不用的代碼(多人維護的時候 總會有垃圾代碼產生)
- 不用的文件(大多是因為需求變更 遺留下來的代碼文件)
- 不用的資源(大多是圖片資源)
前兩項不談 都是體力活(當然 流程越規范 花費的時間越少)
今天主要談談怎麼處理圖片資源
實踐

我一般都是采用folder references的方式來組織資源(就是藍色的文件夾喲 不過可能很多朋友已經用上了Images.xcassets) 相比groups的方式 優點如下
- 直接對資源文件和目錄結構進行調整而不需要修改項目文件
- 資源文件可以重名
- 如果有不同的target 每個target維護不同的根資源文件夾就行了
其他的優缺點對比 我就不在這裡贅述了 相信有經驗的同學都有體會
采用folder references的時候 一般在代碼中是要指明其絕對路徑的
[self.btnCreate setImageN:@"Res/circle/nav_create.png" H:@"Res/circle/nav_create.png" D:nil S:nil];
那麼 要找到未使用的資源 其實就很簡單了
- 找到代碼中所有被引用的資源
- 遍歷資源文件夾 與上面的結果相匹配 找到未引用的資源
腳本
按照上面的邏輯 我用python寫了一個簡單的腳本如下
#!/usr/bin/python # -*- coding: utf-8 -* import os, sys, re, shutil if __name__ == '__main__': used_map = {} resPath = "./MagnetPF/Res/" #資源目錄相對路徑 depDir = "deprecated" #過期目錄 會將未使用文件挪入這個目錄 skipDir = ["message"] #將跳過的目錄 for root, dirs, files in os.walk("./"): for file in files: if file.endswith(".m"): filepath = os.path.join(root, file) f = open(filepath, "r") for line in f: match = re.findall(".*?@/"(Res.*?.png)/".*?", line) #匹配資源文件 if match: for image in match: # print image used_map[image] = 1 #記錄 skipDir.append(depDir) #過期目錄也會一並跳過 for root, dirs, files in os.walk(resPath): for file in files: orginfile = os.path.join(root, file) match = re.findall(".*?(Res.*?.png).*?", orginfile) #將相對路徑過濾出來 if match: matchfile = match[0].replace("@2x","").replace("@3x","") #剔除@2x@3x字樣 print matchfile if not used_map.has_key(matchfile): #檢測到未使用資源 filename = orginfile.split(os.path.sep)[-1] #獲取文件名 relPath = orginfile.replace(resPath,"") #獲取相對路徑 originDir = relPath.split(os.path.sep)[0] #獲取第一層文件夾名(用於跳過篩選) tofile = resPath + depDir + "/" + relPath #目標文件 (將會被復制到這個路徑) topath = tofile.replace(filename,"") #目標文件夾 (若沒有則會創建這個文件夾) if not originDir in skipDir: if not os.path.exists(topath): os.mkdir(topath) print "from: " + orginfile print " to: " + tofile print "" shutil.move(orginfile, tofile)
小結
這個代碼其實還有幾個問題沒有解決
- 若含有資源文件的代碼被注釋 一樣會被忽略而不會被移除(當然 代碼清理也是應該要做的)
- 對於用代碼拼接的資源(比如xx01.png,xx02.png)會無法識別
- 不適用於非folder references方式引用資源的工程
同理 我們可以寫類似的代碼來清理多語言文件 
代碼其實是我上周六現學現賣邊查google邊寫的 所以寫得不好 若是大家有更好的方案 歡迎一起討論學習