IOS中动态方法决议

objective-c提供了一种名为动态方法决议的手段,使得我们可以在运行时动态地为一个selector提供实现。我们只要实现+resolveInstanceMethod:和+resolveClassMethod:方法,并在其中为指定的selector提供实现即可(通过调用运行时函数class_addMethod来添加)。这连个方法都是NSObject中的类方法,其原型为:

+ (BOOL)resolveClassMethod:(SEL)name;

+ (BOOL)resolveInstanceMethod:(SEL)name;

参数name是需要被冬天决议的selector;返回值文档中说是表示动态决议成功与否。但在上面的例子中(不涉及消息转发的情况下),如果在该函数内为指定的selector提供实现,无论返回YES还是NO,编译运行都是正确的;但如果在该函数内并不真正为selector提供实现,无论返回YES还是NO,运行都会crash,道理很简单,selector并没有对应的而实现,而又没有实现消息转发。resolveInstanceMethod是为对象方法进行决议,而resolveClassMethod是为类方法进行决议。

//
//  Foo.m
//  DeepIntoMethod
//
//  Created by 飘飘白云 on 12-11-13.
//  Copyright (c) 2012年 kesalin@gmail.com All rights reserved.
//


#import "Foo.h"
#include <objc/runtime.h>


void dynamicMethodIMP(id self, SEL _cmd) {
    NSLog(@" >> dynamicMethodIMP");
}


@implementation Foo


-(void)Bar
{
    NSLog(@" >> Bar() in Foo");
}


+ (BOOL)resolveInstanceMethod:(SEL)name
{   
    NSLog(@" >> Instance resolving %@", NSStringFromSelector(name));
    
    if (name == @selector(MissMethod)) {
        class_addMethod([self class], name, (IMP)dynamicMethodIMP, "v@:");
        return YES;
    }
    
    return [super resolveInstanceMethod:name];
}


+ (BOOL)resolveClassMethod:(SEL)name
{
    NSLog(@" >> Class resolving %@", NSStringFromSelector(name));
    
    return [super resolveClassMethod:name];
}


@end


理解这段代码:

1、首先判断是否实现了resolveInstanceMethod,如果没有实现,返回NULL,进入下一步处理

2、如果实现了,调用resolveInstanceMethod,获取返回值

3、如果返回值为YES,表示resolveInstanceMethod声称它已经提供了selector的实现,因此再次查找method list,如果依然找到相应的IMP,则返回该实现,否则提示警告信息,返回NULL,进入下一步处理

4、如果返回值为NO,返回NULL,进入下一步处理。

只有在resolveInstanceMethod的实现中没有真正为selector提供实现,并返回NO的情况下才会进入消息转发流程;否则绝不会进入消息转发流程,程序要么调用正确的动态方法,要么crash。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值