中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS中怎么刪除無用的類

發布時間:2021-07-24 15:39:44 來源:億速云 閱讀:234 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關iOS中怎么刪除無用的類,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

引用類地址

可以通過Mac自帶的工具otool打印Mach-o中的段信息,需要注意的是模擬器和真機對應的可執行文件,數據的存儲方式不同需要加以區分。

可以通過file命令獲取到arch。

#binary_file_arch: distinguish Big-Endian and Little-Endian#file -b output example: Mach-O 64-bit executable arm64binary_file_arch = os.popen('file -b ' + path).read().split(' ')[-1].strip()

在取類地址的時候區分x86_64和arm。

def pointers_from_binary(line, binary_file_arch): line = line[16:].strip().split(' ') pointers = set() if binary_file_arch == 'x86_64':  #untreated line example:00000001030cec80d8 75 15 03 01 00 00 00 68 77 15 03 01 00 00 00  pointers.add(''.join(line[4:8][::-1] + line[0:4][::-1]))  pointers.add(''.join(line[12:16][::-1] + line[8:12][::-1]))  return pointers #arm64 confirmed,armv7 arm7s unconfirmed if binary_file_arch.startswith('arm'):  #untreated line example:00000001030bcd2003138580 00000001 03138878 00000001  pointers.add(line[1] + line[0])  pointers.add(line[3] + line[2])  return pointers return None

通過otool -v -s __DATA __objc_classrefs獲取到引用類的地址。

def class_ref_pointers(path, binary_file_arch):  ref_pointers = set()  lines = os.popen('/usr/bin/otool -v -s __DATA __objc_classrefs %s' % path).readlines()  for line in lines:    pointers = pointers_from_binary(line, binary_file_arch)    ref_pointers = ref_pointers.union(pointers)  return ref_pointers

所有類地址

通過otool -v -s __DATA __objc_classlist獲取所有類的地址。

def class_list_pointers(path, binary_file_arch):  list_pointers = set()  lines = os.popen('/usr/bin/otool -v -s __DATA __objc_classlist %s' % path).readlines()  for line in lines:    pointers = pointers_from_binary(line, binary_file_arch)    list_pointers = list_pointers.union(pointers)  return list_pointers

取差集

用所有類信息減去引用類的信息,此時我們可以拿到未使用類的地址信息。

unref_pointers = class_list_pointers(path, binary_file_arch) - class_ref_pointers(path, binary_file_arch)

符號化

通過nm -nm命令可以得到地址和對應的類名字。

def class_symbols(path):  symbols = {}  #class symbol format from nm: 0000000103113f68 (__DATA,__objc_data) external _OBJC_CLASS_$_EpisodeStatusDetailItemView  re_class_name = re.compile('(\w{16}) .* _OBJC_CLASS_\$_(.+)')  lines = os.popen('nm -nm %s' % path).readlines()  for line in lines:    result = re_class_name.findall(line)    if result:      (address, symbol) = result[0]      symbols[address] = symbol  return symbols

過濾

在實際分析的過程中發現,如果一個類的子類被實例化,父類未被實例化,此時父類不會出現在__objc_classrefs這個段里,在未使用的類中需要將這一部分父類過濾出去。使用otool -oV可以獲取到類的繼承關系。

def filter_super_class(unref_symbols):  re_subclass_name = re.compile("\w{16} 0x\w{9} _OBJC_CLASS_\$_(.+)")  re_superclass_name = re.compile("\s*superclass 0x\w{9} _OBJC_CLASS_\$_(.+)")  #subclass example: 0000000102bd8070 0x103113f68 _OBJC_CLASS_$_TTEpisodeStatusDetailItemView  #superclass example: superclass 0x10313bb80 _OBJC_CLASS_$_TTBaseControl  lines = os.popen("/usr/bin/otool -oV %s" % path).readlines()  subclass_name = ""  superclass_name = ""  for line in lines:    subclass_match_result = re_subclass_name.findall(line)    if subclass_match_result:      subclass_name = subclass_match_result[0]    superclass_match_result = re_superclass_name.findall(line)    if superclass_match_result:      superclass_name = superclass_match_result[0]    if len(subclass_name) > 0 and len(superclass_name) > 0:      if superclass_name in unref_symbols and subclass_name not in unref_symbols:        unref_symbols.remove(superclass_name)      superclass_name = ""      subclass_name = ""  return unref_symbols

為了防止一些三方庫的誤傷,還可以去過濾一些前綴,或者是是僅保留帶有某些前綴的類。

for unref_pointer in unref_pointers:    if unref_pointer in symbols:      unref_symbol = symbols[unref_pointer]      if len(reserved_prefix) > 0 and not unref_symbol.startswith(reserved_prefix):        continue      if len(filter_prefix) > 0 and unref_symbol.startswith(filter_prefix):        continue      unref_symbols.add(unref_symbol)

最終結果保存在腳本目錄下。

script_path = sys.path[0].strip()f = open(script_path+"/result.txt","w")f.write( "unref class number:  %d\n" % len(unref_symbles))f.write("\n")for unref_symble in unref_symbles:  f.write(unref_symble+"\n")f.close()

這個思路在一定程度上能夠減少代碼的冗余,減小包的體積。因為是靜態分析,不能包括動態調用的情況,對于需要刪除的類需要進一步的確認。

以上就是iOS中怎么刪除無用的類,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

ios
AI

余姚市| 新余市| 洞头县| 偃师市| 改则县| 甘肃省| 巴彦淖尔市| 汝南县| 义乌市| 阜康市| 会理县| 句容市| 镇江市| 东源县| 元朗区| 高密市| 泾源县| 青岛市| 孝昌县| 乌鲁木齐县| 巫溪县| 林周县| 财经| 阜新| 理塘县| 堆龙德庆县| 平和县| 治县。| 拜泉县| 东平县| 四平市| 方山县| 柏乡县| 深水埗区| 元朗区| 平南县| 新乡县| 南陵县| 玛沁县| 华宁县| 厦门市|