runtime的運用: (如下代碼所有都基於Dog類建立的一個對象:dog)數組
1.使用id類型來建立變量以便接受不一樣類型的對象spa
2.使用 [person performSelector:@selector(test2:) withObject:@"傳入參數"];來動態的調用方法;orm
3.使用objc_setAssociatedObject(id object,const void *key,id value,objc_AssociationPolicy policy)爲對象object添加額外的存儲空間.對象
4.動態copy對象ci
在MRC模式下使用:字符串
Dog *dog = [Dognew];get
dog.name = @"1234";cmd
dog.age = 3;源碼
Dog *copyDog = object_copy(dog,sizeof(dog));string
5.動態設置對象的歸屬類object_setClass 或者得到對象的歸屬類
object_setClass以下列代碼:
Dog *dog = [Dognew];
NSLog(@"dog.class==%@",[dogclass]);
NSLog(@"%@",object_setClass(dog, [Catclass])); //Object_setClass的返回值爲對象原來的所屬類
NSLog(@"dog.class==%@",[dogclass]);
將輸出:
dog.class==Dog
Dog
dog.class==Cat
object_getClass 以下代碼:
Dog *dog = [Dognew];
Class class = object_getClass(dog);
NSLog(@"%@",class);
將輸出:Dog
也就是動態的得到dog對象的所屬類
5.respondsToSelector 以及 performSelector
respondsToSelector,用來判斷對象是否能夠調用對應的方法,傳入一個SEL類型的值
performSelector用來直接使用對象調用方法,傳入一個SEL類型的參數,常常將二者結合來用,示例以下:
if ([dog respondsToSelector:@selector(funOfDog)]) {
[dog performSelector:@selector(funOfDog)];
}else if([dogrespondsToSelector:@selector(funOfCat)]){
[dog performSelector:@selector(funOfCat)];
}
判斷dog類能夠相應那種方法而且直接調用它.
6.使用object_getClassName獲取類名,只不過是C+字符串的格式
const char * className =object_getClassName(dog);
printf("%s",className);
輸出:Dog
7.爲對象添加方法
爲Dog類添加私有方法,由於這個方法是動態添加的,因此只能使用使用respondsToSelector來動態的調用這個方法,不然的話,編譯是不經過的,由於在被添加的類中,該方法即沒有實現也沒有聲明.
class_addMethod([Dogclass], @selector(dogAddFun:str2:), (IMP)funOfAdd,"i@:@@");
if ([dog respondsToSelector:@selector(dogAddFun:str2:)]) {
int number = [dogperformSelector:@selector(dogAddFun:str2:)withObject:@"1234"withObject:@"5678"];
NSLog(@"%d",number);
}else
NSLog(@"方法沒有添加成功");
int funOfAdd(idself,SEL_cmd,NSString *str,NSString* str2){
return (int)(str.length + str2.length);
} //返回兩個字符串長度相加的和
8.獲取一個類的全部方法 class_copyMethodList
u_int count;
Method *methods = class_copyMethodList([dog class], &count);
for (int i = 0 ; i < count; i ++){
SEL name = method_getName(methods[i]);
printf("%s\n",sel_getName(name));
}
其中,class_copyMethodList的兩個參數分別爲類名和統計方法數量的無符號整形的變量地址,其返回值爲一個包含該類全部objc_method方法的數組
method_getName傳入的參數是該類中的objc_method對象,返回值爲該方法對應的SEL,其在runtime源碼中的實現以下:
SEL method_getName(Method m)
{
if (!m) return NULL;
return oldmethod(m)->method_name;
}
sel_getName(name)則是經過SEL獲取該SEL對應的方法名
9.獲取一個類的全部屬性名
u_int count;
objc_property_t* properites = class_copyPropertyList([dog class], &count);
for(int i = 0 ; i < count;i ++){
const char* name= property_getName(properites[i]);
printf("%s\n",name);
}
10.系統類方法的替換
能夠互換兩個方法的實現 ,可是沒感受有什麼用途 ,估計是沒遇到有次需求的問題
Method method1 = class_getInstanceMethod([NSString class],@selector(lowercaseString));
Method method2 = class_getInstanceMethod([NSString class],@selector(uppercaseString));
method_exchangeImplementations(method1, method2);
NSLog(@"%@",[@"aaaaaa" lowercaseString]);
NSLog(@"%@",[@"BBBBB" uppercaseString]);
Method method1 = class_getInstanceMethod([dog class],@selector(funOfDog));
Method funMethod = class_getInstanceMethod([self class],@selector(replaseFun));
IMP imp = method_getImplementation(funMethod);
method_setImplementation(method1, imp);
[dog funOfDog];
funOfDog是dog類裏定義的方法,replaseFun是在調用控制器裏定義的方法,兩個方法都只有一條輸出語句,執行完上述語句後,dog調用funOfDog執行的是在本控制器裏輸出的語句.