前幾天有一篇文章一個(gè)不規(guī)范的 Category 寫(xiě)法導(dǎo)致的“血案”,很有意思。
測(cè)試代碼如下:
//NSObject+Test.h
@interface NSObject (Test)
- (void)func;
@end
@implementation NSObject (Test)
- (void)func {
printf("hello, world");
}
@end
在兩個(gè).m文件里引用了NSObject+Test.h,查看Mach-O信息:
Contents of (__DATA_CONST,__objc_catlist) section
0000000100003050 0x100004090 __OBJC_$_CATEGORY_NSObject_$_Test
name 0x1000015c3 Test
cls 0x0 _OBJC_CLASS_$_NSObject
instanceMethods 0x100004058
entsize 24
count 2
name 0x100001638 func
types 0x100002363 v16@0:8
imp 0x100000ed0 -[NSObject(Test) func]
name 0x100001638 func
types 0x100002363 v16@0:8
imp 0x100000ea0 -[NSObject(Test) func]
可以看到NSObject只有一個(gè)分類(lèi),但是有兩個(gè)同名方法,他們的函數(shù)地址不同。兩個(gè)方法對(duì)應(yīng)兩次引用。除了會(huì)引起包大小增加,分類(lèi)同名方法的覆蓋(共存)可能因?yàn)閷?shí)現(xiàn)不同,會(huì)引起其他邏輯問(wèn)題,解決這種問(wèn)題可能會(huì)耗費(fèi)不少時(shí)間。
這種情況雖然編譯的時(shí)候會(huì)有警告,但是警告可能會(huì)被忽視掉。因此我
在 Snake 里增加了類(lèi)重復(fù)方法的檢測(cè)。
snake -d path/to/binary -l path/to/linkmap
-[NSObject(Test)#TCat func]