1.消息發送
OC:運行時機制,消息機制是運行時機制最重要的機制
消息機制:任何方法調用,本質都是發送消息
SEL:方法編號,根據方法編號就可以找到對應方法實現
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat)];
// 讓p發送消息
// objc_msgSend(p, @selector(eat));
// objc_msgSend(p, @selector(run:),10);帶參數的消息
這是消息發送的對象方法。
// 獲取類對象
Class personClass = [Person class];
[personClass performSelector:@selector(eat)];
// 運行時
objc_msgSend(personClass, @selector(eat));
這是消息發送的類方法。
2.方法交換
// 交換方法實現,方法都是定義在類里面
// class_getMethodImplementation:獲取方法實現
// class_getInstanceMethod:獲取對象
// class_getClassMethod:獲取類方法
// IMP:方法實現
// Class:獲取哪個類方法
// SEL:獲取方法編號,根據SEL就能去對應的類找方法
Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
// xmg_imageNamed
Method xmg_imageNamedMethod = class_getClassMethod([UIImage class], @selector(xmg_imageNamed:));
// 交換方法實現
method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);
實列:
-
(UIImage *)xmg_imageNamed:(NSString *)imageName
{
// 1.加載圖片
UIImage *image = [UIImage xmg_imageNamed:imageName];// 2.判斷功能
if (image == nil) {
NSLog(@"加載image為空");
}return image;
}
這樣就實現了兩個方法的交換。
3.動態添加方法
// performSelector:動態添加方法,聲明一個類,并不提供eat:這個方法
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat:) withObject:@111];
在Person類中,
// 動態添加方法,首先實現這個resolveInstanceMethod
// resolveInstanceMethod調用:當調用了沒有實現的方法沒有實現就會調用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法沒有實現,從而動態添加方法
// sel:沒有實現方法
-
(BOOL)resolveInstanceMethod:(SEL)sel
{
// NSLog(@"%@",NSStringFromSelector(sel));// 動態添加eat方法
if (sel == @selector(eat:)) {/* cls:給哪個類添加方法 SEL:添加方法的方法編號是什么 IMP:方法實現,函數入口,函數名 types:方法類型 */ // @:對象 :SEL class_addMethod(self, sel, (IMP)aaaa, "v@:@"); // 處理完 return YES;
}
return [super resolveInstanceMethod:sel];
}
聲明一個C語言的函數來動態添加
void aaaa(id self, SEL _cmd, id param1)
{
NSLog(@"調用eat %@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}
4.分類動態添加屬性
列如給NSObject添加一個name屬性
(void)setName:(NSString *)name
{
// 添加屬性,跟對象
// 給某個對象產生關聯,添加屬性
// object:給哪個對象添加屬性
// key:屬性名,根據key去獲取關聯的對象 ,void * == id
// value:關聯的值
// policy:策越
objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// _name = name;
}(NSString *)name
{
return objc_getAssociatedObject(self, @"name");
}