近日因爲種種緣由,須要把代碼裏面的類所有都修改一遍類名。python
在網上找了一圈相關的開源庫,沒有發現有合適滿意的,始終都存在一些問題,要麼出現誤修改,要麼把方法名或者屬性名也給修改了等等狀況。git
因而決定掏出生疏的Python來寫一個。程序員
批量修改類名須要解決四個問題:github
因爲本身前不久寫了一個獲取target對應的編譯以及資源文件的工具MacPbxprojHelper,利用其來獲取到target對應的類名寫入文件,而後用python來讀取文件獲取到須要修改的類名,實時上初版我也是這麼作的,可是不夠優雅,明明一個腳本能解決的事,爲何須要那麼多步操做呢?數組
利用python直接遍歷文件夾獲取類名,沒錯就決定是你了。 其實用python遍歷文件實現起來特別簡單快捷。可是其中也有可能存在的問題,例如咱們的項目中包含有部分資源文件,而資源文件的後綴名是不定的,可是實際咱們只須要.m以及.mm結尾的文件前綴做爲咱們的類名,固然其中包含有類目也須要過濾掉。而且考慮到咱們具有一些特殊的需求,須要過濾某些文件甚至某些文件夾下的文件等等。我這邊的腳本都有考慮到xcode
實現代碼以下:bash
def getClassNames(filepath):
#讀取文件名入數組
#過濾文件夾
filterDirs = ["ThirdKit/","小說/"]
#過濾文件
filterFiles = []
classNames = []
#遍歷filepath下全部文件,包括子目錄
for root, dirs, files in os.walk(filepath):
for name in files:
path = os.path.join(root, name)
#過濾文件夾
isFilterDir = 0
for filterDir in filterDirs:
if filterDir in path:
isFilterDir = 1
break
if isFilterDir != 1:
if ".m" in name:
splitNames = name.split(".m")
#只選擇.m和.mm結尾的文件
if splitNames[1] == "" or splitNames[1] == "m":
cn = splitNames[0]
#過濾文件
isFilterFile = 0
for ff in filterFiles:
if ff == cn:
isFilterFile = 1
if isFilterFile != 1:
#過濾類目
if cn.find("+") == -1:
print(cn)
classNames.append(cn)
return classNames
複製代碼
在我搜集到的開源的腳本中,有極大比例的一部分是直接經過類名替換,其實這特別容易出現誤改。好比我有一個類名爲ABC,一個類名爲AB,那麼ABC就可能出現被修改兩次的狀況。因此我這邊就採用笨辦法,先敲定類名出現的場景,根據其場景設定規則,只有出現類名出如今這些規則中時,纔去替換,這樣就能夠保證100%的正確率。(這也是大坑,由於不一樣的程序員書寫習慣的問題,致使規則的定義實際極度繁瑣,並且會出現部分遺漏,每一次遺漏後,我都須要添加規則再重跑來驗證··)app
下面就是這個腳本最大的貢獻·· 自認爲基本涵蓋完了類名的出現場景(若是有沒有涵蓋的,請記得必定聯繫我!!),一共37種規則,運用這37種規則,作到了一次腳本,既完美修改,無需在動代碼就能夠直接運行而且不會有閃退問題··工具
#一開始構思了 14個 後來....
rule_1 = '"' + cn + '.' #引用修改
rule_2 = '"' + cn + '"' #類名被直接使用
rule_3 = ':' + cn + ' ' #繼承 後續有空格
rule_4 = ':' + cn + '\n' #類名後面是換行
rule_5 = ' ' + cn + '<'
rule_6 = ' ' + cn + '\n' #類名後面是換行
rule_7 = ' ' + cn + ' '
rule_8 = ' ' + cn + '('
rule_9 = '[' + cn + ' '
rule_10 = '[' + cn + '*'
rule_11 = '(' + cn + '*'
rule_12 = ')' + cn + '*'
rule_13 = ' ' + cn + '*'
rule_14 = ' ' + cn + '\n'
rule_15 = '(' + cn + ' '
rule_16 = ' ' + cn + ';'
rule_17 = ',' + cn + ' '
rule_18 = ',' + cn + '*'
rule_19 = ')' + cn + ' '
rule_20 = ',' + cn + ';'
rule_21 = ' ' + cn + ','
rule_22 = '<' + cn + '*' #被當作協議 遵照類
rule_23 = '<' + cn + ' '
rule_24 = ',' + cn + ','
rule_25 = ' ' + cn + ':'
rule_26 = ':' + cn + '//' #後面跟註釋的、、我TM。。
rule_27 = ' ' + cn + '//'
rule_28 = ' ' + cn + '{' #後面跟大括號的··
rule_29 = ')' + cn + '<' #爲何遵照協議 也用了 實際類名 沒有用ID
rule_30 = '(' + cn + '.' #爲何類要使用.語法
rule_31 = ' ' + cn + '.' #類名調用.語法
rule_32 = '!' + cn + '.'
rule_33 = ':' + cn + '.' #類名調用點語法 被當作參數傳入
rule_34 = '[' + cn + '\n' #類名被換行
rule_35 = ':' + cn + '<' #繼承類名後面 直接接入協議 默認實際是不存在這個問題的
rule_36 = '"' + cn + '_' #類取名有下劃線以及數字 以及經過工廠用數字來建立的狀況
rule_37 = '"' + cn + '%' #類取名有數字 以及經過工廠用數字來建立的狀況
複製代碼
這個問題其實很好解決,利用python的os庫就能夠直接rename,只是須要拼接全路徑。而且在給類文件重命名的時,須要注意前綴和後綴添加的位置,不要添加到.h和.m後面去了便可。ui
這裏又和第二個問題同樣須要定義必定規則,才能確保不會出現誤替換,可是這個規則和上面比起來簡直是小巫見大巫。規則以下:
def pbRule(cn):
rule_1 = '=' + cn + "."
rule_2 = ' ' + cn + "."
rule_3 = '/' + cn + "."
rule_4 = '"' + cn + "."
複製代碼
以上,問題都解決了。
----------腳本說明----------
腳本用於批量修改類名
腳本可傳入四個參數
一、待處理的文件路徑. example-->'./KanManHua'
二、待修改的pbxproj文件地址 example-- >'./KanManHua.xcodeproj/project.pbxproj'
三、類名前綴 example-->'MHT_'
四、類名後綴 example-->'_MHT'
其中前三個參數爲必傳參數 劃重點,要考
----------請開心使用---------
另腳本支持 -h --help 操做
複製代碼
當參數錯誤時,也有對應提示以及上述幫助信息
示例:
python changeClassName.py ./KanManHua ./KanManHua.xcodeproj/project.pbxproj MHT_ _MHT
複製代碼
示例:
python changeClassName.py
python changeClassName.py -h
python changeClassName.py --help
複製代碼
因爲我司還有需求修改指定 target的類名,實際也有一套能夠僅僅只修改target類名的方法,可是因爲使用要複雜一點,首先要提取target對應的編譯類,再使用腳原本修改,修改使用到我以前發佈的一個工具類MacPbxprojHelper,若有須要的話請和我聯繫。 聯繫方式:357863248@qq.com