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");
}