由于昨天提到运行时,今天顺便讲解一下,不讲太多,不然篇幅太长,大家要么看不下去,要么容易晕
这里就不分层了,可以直接复制代码,方便运行,
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1.通过运行时添加一个类
// 1.1设置类名
const char *className = "MyClass";
// 1.2通过类名获取类
Class idClass = objc_getClass(className);
// 1.3如果类不存在
if(!idClass){
// 创建运行类父类
Class superClass = [NSObject class];
idClass = objc_allocateClassPair(superClass, className, 0);
}
// 2.为类添加方法(ios拓展29)
IMP myimp = imp_implementationWithBlock(^(NSString *_self, NSString *str){
NSLog(@"1");
NSLog(@"%@-2-%@",_self,str);//_self没有打印
});
class_addMethod(idClass, @selector(did:), (IMP)myimp, "");
/*
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
参数说明:
cls:被添加方法的类
name:可以理解为方法名,这个貌似随便起名,比如我们这里叫sayHello2
imp:实现这个方法的函数
types:一个定义该函数返回值类型和参数类型的字符串,这个具体会在后面讲,
=======>其实不填写好像也没问题<============
*/
// 3 注册类 ()
objc_registerClassPair(idClass);
}
#pragma mark- 方法调用 -
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
Class MyCls = NSClassFromString(@"MyClass");
id instance = [MyCls new];
[instance performSelector:@selector(did:) withObject:@"zhao"];//就算增加到2个参数,也只能打印一个
}
/*
class_addMethod(idClass, @selector(did:), (IMP)myimp, "v@@“);
其中types参数为"v@@“,按顺序分别表示:
v ==> 返回值类型void,若是i则表示int
@ ==> 参数id(_self)
@ ==> id(str)
这些表示方法都是定义好的(Type Encodings),关于Type Encodings的其他类型定义请参考官方文档
*/
@end
运行结果
附其他方法:
// 添加成员变量
// class_addIvar
// 添加关联属性
// class_addProperty
// 添加协议
// class_addProtocol
[Type Encodings](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html)
网友评论