笔记:利用 runtime 交换方法、给分类动态添加属性

第一次写博客,有些小紧张,如有不对的地方还请大牛们及时指出,在此先感谢各位大牛了...


一、利用 runtime 交换方法:

1、交换方法的实现

#import "UIImage+mImage.h"

@implementation UIImage (mImage)
+(void)load{
    //load 把类加载到内存时调用,只会调用一次,在这里用 runtime 交换方法,能够确保在调用方法之前交换。
    //1、 获取方法的地址 class_getClassMethod(参数1->类,参数2->方法名) (获取 'get' 某个类 ‘class' 的方法 ’method‘
    Method imageNamedMethod = class_getClassMethod(self, @selector(imageNamed:));
    Method in_imageNamedMethod = class_getClassMethod(self, @selector(in_imageNamed:));
    
    //2、交换方法的地址,相当于交换实现方式 method_exchangeImplementations(参数1->方法地址1,参数2->方法地址2) (方法 ’method‘ 交换 ’exchange‘ 实现方式 ’Implementations‘)
    method_exchangeImplementations(imageNamedMethod, in_imageNamedMethod);
    
    
}

// 调用 imageNamed => in_imageNamed
// 调用 in_imageNamed => imageNamed
+(UIImage *)in_imageNamed:(NSString *)name{
    UIImage *image = [UIImage in_imageNamed:name];
    if (image) {
        NSLog(@"runtime交换方法--加载成功");
    }else{
        NSLog(@"runtime交换方法--加载失败");
    }
    return image;
}
@end

2、调用

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iamgeV;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    UIImage *image = [UIImage imageNamed:@"XXX"];
    _iamgeV.image = image;
   
}
3、打印
2018-03-16 12:47:43.131559+0800 2[2475:2056911] runtime交换方法--加载成功


二、给分类动态添加属性:给分类动态添加属性实质上就是将这个属性跟这个类关联起来,例如给 NSObject 添加一个分类,在分类里给 NSObject 添加一个 title 的属性,实质上就是将 title 属性跟 NSObject 类关联起来。

1、动态添加属性

#import "NSObject+Title.h"
#import <objc/message.h>
@implementation NSObject (Title)
// 在分类里是不能给类添加属性的,即使是用了 @property 也只是生成了 set 和 get 方法的声明,并没有生成带下滑线的属性以及 set、get 方法的实现。runtime 可以通过 objc_setAssociatedObject(id object->要关联的对象, const void *key->关联的属性名称, id value->关联的属性值, objc_AssociationPolicy policy->保存策略)方法将属性跟类关联起来。(设置 ‘set’ 关联 ‘associatded' 到类 ’object‘)
-(void)setTitle:(NSString *)title{
    // objc_setAssociatedObject
    objc_setAssociatedObject(self, @"title", title, OBJC_ASSOCIATION_COPY);
    
}
-(NSString *)title{
    // objc_getAssociatedObject
    return objc_getAssociatedObject(self, @"title");
}
@end


2、调用验证

#import "ViewController.h"
#import "NSObject+Title.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   // 调用
    NSObject *objc = [[NSObject alloc] init];
    objc.title = @"这是 runtime 动态关联的属性";
    NSLog(@"runtime 动态关联属性成功,title = %@", objc.title);
}

3、打印

2018-03-16 14:55:20.751379+0800 2[2515:2098412] runtime 动态关联属性成功,title = 这是 runtime 动态关联的属性


注:本文参考了《iOS模式详解runtime面试工作》,用自己比较能够理解的方式做了一下笔记,在此感谢原文作者!




猜你喜欢

转载自blog.csdn.net/lichuandev/article/details/79581048