最近經(jīng)常會(huì)被問(wèn)起知道RunTime碍沐,而且也在項(xiàng)目中的 "UIActionSheet+Blocks.h" 看到了它的影子蚓再。所以根據(jù)自己的理解寫(xiě)點(diǎn)心得站粟,理解的也許有誤差的地方而且理解的也不是很全面浦妄,以后會(huì)為這篇RunTime多多修改和添加的呢灶。
首先什么是 RunTime吴超?RunTime 為運(yùn)行機(jī)制,用c和匯編寫(xiě)的鸯乃。因?yàn)镺C語(yǔ)言是一個(gè)動(dòng)態(tài)的語(yǔ)言鲸阻,它會(huì)把一些工作推遲到運(yùn)行時(shí)去執(zhí)行。這樣但靠編譯器是不夠的(c語(yǔ)言可以)缨睡,所有RunTime就有了存在的意義赘娄。RunTime分為“mordern”和"leyacy"兩個(gè)版本,mordern是我們現(xiàn)在使用的宏蛉,是支持64位的,leyacy是之前的性置,是在32位環(huán)境下使用的拾并。
當(dāng)我們調(diào)用一個(gè)[objc makeTest]
的時(shí)候,我們都知道是這個(gè)objc這個(gè)對(duì)象去調(diào)用makeTest這個(gè)方法鹏浅,在RunTime下它會(huì)轉(zhuǎn)化成objc_msgSend(obj,@selector(makeTest))
,在objc_msgSend這個(gè)函數(shù)中嗅义,會(huì)通過(guò)obj的isa指針去找到obj相對(duì)應(yīng)的類,然后在這個(gè)類的cache(方法的緩存池隐砸,這樣可以更快更高效的去查找方法)中之碗,根據(jù)SEL(方法選擇器)去查找對(duì)應(yīng)的makeTest方法,如果cache中沒(méi)有的話季希,再去這個(gè)類的methodList(方法列表)中查找褪那,如果在methodList沒(méi)有的話就去它的superClass中去查找幽纷,如果查找到了,就把這個(gè)makeTest方法放入cache中以方便下次查找博敬。
下面介紹幾個(gè)RunTime中的方法友浸,也可以去<objc./runtime.h>
文件中去查看。
1
id object_copy(id obj, size_t size)
對(duì)象拷貝偏窝,內(nèi)存地址為同一個(gè)收恢。2
id object_dispose(id obj )
釋放對(duì)象 作用和release差不多.3
Class object_getClass(id obj)
獲取一個(gè)類4
const char *object_getClassName(id obj)
獲取一個(gè)類的類名 和NSStringFormClass的作用一樣-
5
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
給一個(gè)類添加方法 class:類, SEL name: 方法名 IMP:這個(gè)類似于函數(shù)指針的東西,后面跟函數(shù)名字祭往, types為參數(shù).u_int count; Method *method = class_copyMethodList([CustomClass class], &count); for (int i = 0 ; i < count; ++i) { SEL name = method_getName(method[i]); NSString *strName = [NSString stringWithCString:sel_getName(name) encoding:NSUTF8StringEncoding]; NSLog(@"%@", strName); } ``` 這是自己寫(xiě)的一個(gè)獲取CustomClass(隨便寫(xiě)的一個(gè)類)的所有方法伦意,我理解為它返回的是一個(gè)關(guān)于方法的數(shù)組,然后根據(jù) method_getName() 把方法轉(zhuǎn)換為方法選擇器硼补,在根據(jù)sel_getName(name) 轉(zhuǎn)為c語(yǔ)言的字符串驮肉,然后一次打印出來(lái)
-
6
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
這是返回某個(gè)類中所有的屬性u_int mcount; objc_property_t *property = class_copyPropertyList([CustomClass class], &mcount)count); for ( int i = 0 ; i < mcount; ++i) { const char* propertyName= property_getName(property[i]); NSString *strName = [NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]; NSLog(@"%@",strName); } ```
-
7
Method class_getInstanceMethod(Class cls, SEL name)
替換某個(gè)的類的方法CustomClass *custom =[ [CustomClass alloc]init]; Method mMethod= class_getInstanceMethod([CustomClass class], @selector(fun1));un1)) Method mMethod1 = class_getInstanceMethod([CustomClass class], @selector(fun2));
我在這個(gè)類中寫(xiě)了fun1(執(zhí)行打印fun1)和fun2(去打印fun2)的兩個(gè)方法,然后我去執(zhí)行這個(gè)方法 當(dāng)我去執(zhí)行[ custom
fun1]的時(shí)候打印出來(lái)的是fun2 里面的方法已經(jīng)替換的括勺,我的理解
是fun1的IMP指向了fun2所對(duì)應(yīng)的執(zhí)行函數(shù)缆八。他們替換了IMP的指向函數(shù)
- 8 在項(xiàng)目的UIActionSheet+Blocks.h 看到
objc_setAssociatedObject(self,
UIActionSheetTapBlockKey, tapBlock, OBJC_ASSOCIATION_COPY);`
這個(gè)函數(shù),他的作用是用了添加屬性疾捍,self為為那個(gè)類添加,(這里是本類)奈辰,UIActionSheetTapBlockKey
是添加屬性對(duì)應(yīng)的key,必須為唯一標(biāo)示乱豆,tapBlock 為添加的屬性奖恰, OBJC_ASSOCIATION_COPY是屬性類型,這里是copy (因?yàn)樘砑拥氖莃lock 所有用的是copy) 然后通過(guò)objc_getAssociatedObject(self, UIActionSheetTapBlockKey);
可以獲得這個(gè)屬性宛裕。
(總結(jié)的不是很全瑟啃,有深入了解的可以多多指點(diǎn),謝謝)