门户手机网站模板,写作网站可以签约未成年吗,沈阳专业网站建设公司,wordpress 主题制作 functions.php运行时#xff08;runtime#xff09; 运行时是OC的重要特性#xff0c;也是OC动态性的根本支撑。动态#xff0c;如果利用好了#xff0c;扩展性就很强。当然了#xff0c;OC的动态性只能算是一个一般水平。与swift、java这种强类型校验的语言相比#xff0c;OC动态性很…运行时runtime 运行时是OC的重要特性也是OC动态性的根本支撑。动态如果利用好了扩展性就很强。当然了OC的动态性只能算是一个一般水平。与swift、java这种强类型校验的语言相比OC动态性很强和js这种纯动态的语言随时给类增加函数、属性相比OC的动态性就弱很多。动态可以帮助我们在运行时修改类的属性、函数、甚至创建一个新类
相关知识点
消息机制 OC中的方法调用、属性读写等都是通过消息机制来处理的当我们调用一个方法时其实是向那个实例发送了一个消息包含类方法类本身是Class的实例。所以后面的一些功能特点其实也使用了消息机制的特性这里我们主要说说消息转发。
OC的函数调用实际上发送了一条消息那调用过程就是消息处理过程首先从类方法或者实例方法列表中获取你要调用的方法如果没找到就进入转发流程。转发流程中预留了可扩展的点大致过程是这样的
动态解析此过程如果正确添加了方法就执行方法并结束转发否则继续下面的步骤备用接收者转发给其他类/实例如果不转发则继续下面的步骤完整转发获取方法签名并转发如果正确设置了签名并转发则结束否则继续调用未找到方法函数并抛出异常 动态解析
类方法动态解析resolveClassMethod (BOOL)resolveClassMethod:(SEL)sel {NSString *selName NSStringFromSelector(sel);NSLog(%s : %, __func__, selName);if (sel selector(greet)) {// 动态添加 greet 方法class_addMethod(object_getClass(self), sel, (IMP)greet1, v:);}return NO;
}void greet1(id self, SEL _cmd) {NSLog(Hello from MyClass!);
}
这里我用class_addMethod来动态添加了一个方法方法名是greet方法的实现指向了greet1.还应该注意到class_addMethod的第一个参数他的类型是Class如果写self是不生效的需要用object_getClass(self)才可以。原因是我们要给元类增加方法具体
object_getClass(self) 返回类的 元类meta-class是 self 的类的类对象。self和self.class 返回的是 类对象即当前类本身。
实例方法动态解析resolveInstanceMethod (BOOL)resolveInstanceMethod:(SEL)aSelector {if (aSelector selector(greet)) {class_addMethod(self, aSelector, (IMP)greet1, v:);}return [super resolveClassMethod:aSelector];
}
这里和类方法的创建只是第一个参数有差别其他一样
关于返回值我没发现区别关键还在于是不是正确的添加了方法如果添加了则不再继续后续转发步骤否则不论返回YES还是NO都会继续后面的步骤。
备用接收者
如果 resolveInstanceMethod或class没有正确的添加方法Runtime 会调用 forwardingTargetForSelector: 方法。在这个阶段你可以返回一个对象如果是类方法返回类。Runtime 将会尝试将消息转发给这个对象或类如果这个对象或类能够响应消息消息就被解析了。后面将不再单独区分类还是实例方法名都一样只是方法和-方法的区别
- (id)forwardingTargetForSelector:(SEL)aSelector {if (aSelector selector(greet)) {return [[OtherClass alloc] init];}return [super forwardingTargetForSelector:aSelector]; // 确保继续转发
}
完整转发
如果没有设置备用接收者将进入最后的完整转发阶段Runtime 会调用 methodSignatureForSelector: 方法获取方法的签名然后再调用 forwardInvocation: 方法来处理消息。在 forwardInvocation: 中你可以自定义消息的处理逻辑包括选择使用哪个对象来处理消息。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {return [NSMethodSignature signatureWithObjCTypes:v:];
}- (void)forwardInvocation:(NSInvocation *)anInvocation {// 将消息转发给 OtherClass[anInvocation invokeWithTarget:[[OtherClass alloc] init]];
}
关于signature的书写规则参考
类型编码符号voidvidSEL:intifloatfdoubledchar **BOOLBstruct{name...}pointer (void *)^v 未找到方法
如果最终消息无法解析以上步骤都未处理Runtime 将会调用 doesNotRecognizeSelector: 方法该方法默认会抛出异常导致程序崩溃。
应用消息机制是OC动态特性的一个体现我们可以动态的处理函数调用增加切入操作等。