筆記:利用 runtime 交換方法、給分類動態新增屬性
阿新 • • 發佈:2019-01-04
第一次寫部落格,有些小緊張,如有不對的地方還請大牛們及時指出,在此先感謝各位大牛了...
一、利用 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面試工作》,用自己比較能夠理解的方式做了一下筆記,在此感謝原文作者!