objc 在执行一个方法的时候是如何判断一个方法是否存在的?
- 从本类和父类中查找.
- 检查是否动态添加方法.
- 查看是否存在快速消息转发.
- 查看标准消息转发.
1-4是按照顺序进行的, 若在某个环节查到符合的方法, 下面的查找则终止.
- 我就不具体解释了.
- objc 是一门动态的语言, 它允许在运行时, 向一个类添加属性、方法等. class_addMethod、class_addIvar、class_addProperty、class_addProtocol. 具体使用就不介绍了. 需要重写 resolveInstanceMethod 方法, 在其中判断需要添加的方法, 使用class_addMethod来动态添加方法.
+(BOOL)resolveInstanceMethod:(SEL)aSEL
{
if(aSEL == @selector(methodName)){
class_addMethod(Class cls, SEL name, IMP imp,
const char *types) ;
return YES;
}
return [super resolveInstanceMethod];
}
- NSObject 提供快速消息转发方法, 只要重新
- (id)forwardingTargetForSelector:(SEL)aSelector
之后, 每次在父类本类中找不到, 并且没有找到动态添加方法, 则会走该方法, 你可以在这个方法中, return 目标对象, 则目标对象执行 aSelector. 如果没有重写标准消息转发, 并且 return nil, 则会报 unrecognized selector sent to instance
这个错误.
- (id)forwardingTargetForSelector:(SEL)aSelector
{
Person *person = [[Person alloc]init];
if ([person respondsToSelector:aSelector]) {
return person;
}
return nil;
}
4.标准消息转发, 主要可以实现多对象同时转发
// 生成一个方法, 并存入表中
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
if (!signature) {
signature = [yourObj methodSignatureForSelector:aSelector];
}
return signature; // 将一个新签名的方法放入表中
}
// 实现动态添加方法, 并执行方法
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL seletor = [anInvocation selector];
if ([yourObj respondsToSelector:seletor]) {
[anInvocation invokeWithTarget:yourObj];
}
// 这里可以转发若干个你想转发的对象
}
网友评论