OC - runtime常見用法小結(jié)

消息機(jī)制 - 調(diào)用私有方法

OC的runtime特性,使其沒有嚴(yán)格意義上的私有方法。

objc_getClass()
sel_registerName()
objc_msgSend()

例:
@interface MyObjcet : NSObject
@end

@implementation MyObjcet
- (void)myFunction
{
    NSLog(@"myFunction");
}
@end

//即使myFunction方法沒有通過.h暴露出來,也是可以調(diào)用成功的。
MyObjcet *obj = [MyObjcet new];
objc_msgSend(obj, sel_registerName("myFunction"));

方法交換

很多時(shí)候,我們想要對(duì)系統(tǒng)框架的某些方法添加一些自定義邏輯。繼承是個(gè)解決辦法,但得改代碼,如何盡可能少的侵入項(xiàng)目呢?

class_getClassMethod()
class_getInstanceMethod()
method_exchangeImplementations()

例: NSMutableDictionary的setObject:forKey:方法,當(dāng)obj為nil的時(shí)候就會(huì)拋異常。多寫幾個(gè)if其實(shí)也ok,可是...
+ (void)load
{
  Class clas = [object_getClass([NSMutableDictionary dictionary]) class];
  Method original = class_getInstanceMethod(clas, @selector(setObject:forKey:));
  Method new = class_getInstanceMethod(clas, @selector(he_setObject:forKey:));
  method_exchangeImplementations(original, new);
}

@implementation NSMutableDictionary (HECrashHandle)
- (void)he_setObject:(id)anObject forKey:(id<NSCopying>)aKey{
    if(aKey == nil) return;
    if(anObject == nil){
        [self removeObjectForKey:aKey];
    }else{
        [self he_setObject:anObject forKey:aKey];
    }
}
@end


分類中添加屬性

分類的初衷是為擴(kuò)展方法而存在的,但很多時(shí)候我們需要在分類中添加屬性以滿足需求。

objc_setAssociatedObject()
objc_getAssociatedObject()

例: 為UIView添加屬性myDesc

@interface UIView (Desc)
@property NSString *myDesc;
@end

@implementation UIView (Desc)
- (NSString *)myDesc
{
    return objc_getAssociatedObject(self, _cmd);
}
- (void)setMyDesc:(NSString *)myDesc
{
    objc_setAssociatedObject(self, @selector(myDesc), myDesc, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end

添加方法

這個(gè)我這沒怎么用上,如果有好的使用場景,歡迎在下方的評(píng)論區(qū)一起交流

resolveClassMethod:
resolveInstanceMethod:
class_addMethod()

示例:
void myMethodIMP(id self, SEL _cmd) { .... }

@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)aSEL
{
    if (aSEL == @selector(resolveThisMethodDynamically)) {
          class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
          return YES;
    }
    return [super resolveInstanceMethod:aSEL];
}
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容