1.消息机制:发送消息
runtime只能对象发送消息,所以将类也要转化成类对象
objc_msgSend(person, @selector(eat));
objc_msgSend([Person class], @selector(classEat));
2、交换方法:示例
#import "UIImage+Image.h"
#import <objc/message.h>
@implementation UIImage (Image)
+(void)load
{
/*
**
交换方法实现,方法都是定义在类里面
class_getMethodImplementation: 获取方法实现
class_getInstanceMethod: 获取对象
class_getClassMethod: 获取类方法
*/
Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
Method sz_imageNameMethod = class_getClassMethod([UIImage class], @selector(sz_imageNameMethod:));
//交换方法
method_exchangeImplementations(imageNameMethod, sz_imageNameMethod);
}
+(UIImage *)sz_imageNameMethod:(NSString *)imageNamed
{
//加载图片
UIImage *image = [UIImage sz_imageNameMethod:imageNamed];
//功能判断
if (image == nil) {
NSLog(@"加载image为空");
}
return image;
}
在调用的时候正常书写
UIImage *image = [UIImage imageNamed:@""] ;就可以调用我们自己自定义的方法了,最主要的是我们还可以不用引用头文件
3、动态添加方法
viewcontroller中
Person *person =[[Person alloc]init];
//不带参数
[person performSelector:@selector(eat)];
//带参数
[person performSelector:@selector(eat:) withObject:@1111];
在Person类中动态生成方法带参数
#import "Person.h"
#import <objc/message.h>
@implementation Person
//定义函数
//没有返回值,参数(id,SEL)
void aaaa(id self, SEL _cmd,id tyy)
{
NSLog(@"调用了eat %@ %@ %@",self,NSStringFromSelector(_cmd),tyy);
}
/*
默认一个方法都有两个参数,self,_cmd隐式参数
self:方法调用者
_cmd:调用方法的编号
*/
//动态添加方法,首先实现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 class], sel,(IMP)aaaa, "v@:@");
return YES;
}
return [super resolveInstanceMethod:sel];
}
@end
在Person类中动态生成方法不带参数
#import "Person.h"
#import <objc/message.h>
@implementation Person
//定义函数
//没有返回值,参数(id,SEL)
void aaaa(id self, SEL _cmd)
{
NSLog(@"调用了eat %@ %@",self,NSStringFromSelector(_cmd));
}
/*
默认一个方法都有两个参数,self,_cmd隐式参数
self:方法调用者
_cmd:调用方法的编号
*/
//动态添加方法,首先实现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 class], sel,(IMP)aaaa, "v@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
@end
4、动态给系统类添加属性
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (objc)
@property(nonatomic,strong)NSString *name;
@end
NS_ASSUME_NONNULL_END
#import "NSObject+objc.h"
#import <objc/message.h>
@implementation NSObject (objc)
-(void)setName:(NSString *)name
{
/*
添加属性,跟对象
给某个对象产生关联,添加属性
objc:给哪个对象添加属性
key:属性名,根据key去获取关联的对象
value:关联的值
policy:策略
*/
objc_setAssociatedObject(self,@"name" , name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSString *)name
{
/*
获取属性
*/
return objc_getAssociatedObject(self, @"name");
}
@end
调用:
NSObject *obj =[[NSObject alloc]init];
obj.name = @"ds";
NSLog(@"输出名称%@",obj.name);
字典动态转模型
#import "NSObject+Property.h"
@implementation NSObject (Property)
+(void )createPropertyCodeWithDict:(NSDictionary *)dict
{
NSMutableString *strM = [NSMutableString string];
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull propertyName, id _Nonnull value, BOOL * _Nonnull stop) {
NSLog(@"%@,,,%@",propertyName,[value class]);
//属性代码
NSString *code;
if ([value isKindOfClass:NSClassFromString(@"__NSCFString")]) {
code = [NSString stringWithFormat:@"@property(nonatomic,strong) NSString * %@ ;",propertyName];
}else if([value isKindOfClass:NSClassFromString(@"__NSCFNumber")]){
code = [NSString stringWithFormat:@"@property(nonatomic,assign) int %@ ;",propertyName];
}else if ([value isKindOfClass:NSClassFromString(@"__NSCFArray")]){
code = [NSString stringWithFormat:@"@property(nonatomic,strong) NSArray * %@ ;",propertyName];
}else if ([value isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){
code = [NSString stringWithFormat:@"@property(nonatomic,strong) NSDictionary * %@ ;",propertyName];
}
[strM appendFormat:@"\n%@\n",code];
}];
NSLog(@"%@",strM);
}
@end