runtime一個熟悉又陌生的名詞杜窄,這篇文章只是記錄一下筆者在實例中的使用,都是一些皮毛算途,大神可以忽略塞耕,第一次寫簡書,水平有限嘴瓤,如有錯誤的地方還請指出扫外。
直接進入主題,導(dǎo)入#import <objc/runtime.h>? 頭文件
Associative關(guān)聯(lián):
1廓脆、objc_setAssociatedObject(id_Nonnullobject,constvoid*_Nonnullkey,id_Nullablevalue, objc_AssociationPolicy policy)類似屬性的setter方法筛谚;
2、objc_getAssociatedObject(id_Nonnullobject,constvoid*_Nonnullkey)類似屬性的getter方法狞贱;
案例使用:分類屬性的setter和getter方法
????新建一個Person類的分類刻获,在這個分類中聲明一個屬性@property (nonatomic, copy) NSString *name;因為在分類中的屬性需要手動實現(xiàn)getter和setter方法,所以在方法的實現(xiàn)中就可以用到runtime的這對api分別給屬性賦值和取值,代碼如下:
// name的setter方法
- (void)setName:(NSString*)name {
? ? // 根據(jù)key,給指定對象的屬性賦值
? ? // @param object :需要關(guān)聯(lián)的那個屬性的對象
? ? // @param key :需要關(guān)聯(lián)的那個屬性的鍵蝎毡,是個指針厚柳,這邊我用的是name方法的SEL指針
? ? // @param value :賦值的值,若傳nil沐兵,則清除當(dāng)前存在的關(guān)聯(lián)
? ? // @param policy :關(guān)聯(lián)策略别垮,類似assign,copy,strong
? ? objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
//? name的getter方法
- (NSString*)name {
? ? // 根據(jù)key,取出指定對象值
? ? // @param object :需要取值的那個對象扎谎,是個指針碳想,跟上面的key一樣,這里使用_cmd作為key毁靶,_cmd:指當(dāng)前方法胧奔,即name這個方法的SEL指針
? ? // @param return : 所關(guān)聯(lián)key的值
? ? return objc_getAssociatedObject(self, _cmd);
}
這樣既可以完成分類屬性的setter和getter方法,其實很簡單预吆,這里啰嗦了點龙填。
方法交換MenthodSwizzing
// 交換兩個方法m1、m2的的實現(xiàn)
method_exchangeImplementations(Method m1, Method m2)?
案例使用:
? ? 如果有這樣的一個需求:需要在調(diào)用父類viewDidLoad之前統(tǒng)一做某一些操作拐叉,可用創(chuàng)建一個ViewController的分類岩遗,然后在分類中把需要完成那些操作跟viewDidLoad做交換,然后再執(zhí)行viewDidLoad方法凤瘦,ViewController分類的實現(xiàn)代碼如下:
#import "UIViewController+MethonSwizzing.h"
#import <objc/runtime.h>
@implementationUIViewController (MethonSwizzing)
+ (void)load {
? ? MethodfromM =class_getInstanceMethod([selfclass],@selector(viewDidLoad));
? ? MethodtoM =class_getInstanceMethod([selfclass],@selector(swizzing_viewDidLoad));
? ? method_exchangeImplementations(fromM, toM);
}
// viewDidLoad 和 swizzing_viewDidLoad交換宿礁,執(zhí)行到[super viewDidLoad]的時候會執(zhí)行swizzing_viewDidLoad方法
- (void)swizzing_viewDidLoad {
? ? NSLog(@"交換...");
? ? // 因為已經(jīng)交換了方法,所以執(zhí)行swizzing_viewDidLoad的時候蔬芥,其實是執(zhí)行viewDidLoad方法梆靖,所以不會有循環(huán)調(diào)用的問題
? ? [self swizzing_viewDidLoad];
}
@end
思路大概就是這樣,其實解決這個問題的方法很多坝茎,這只是一個涤姊。