首先,笔者想通过下面一段代码来解释什么是动态方法决议,动态方法决议能做什么。
以上代码执行后会产生什么样的结果?我想大家都应该很清楚,那就是程序会crash,因为我们并未实现方法say:,在AA方法的method list中和它的父类method list中都找不到其相应实现,所以会crash 而我们今天的主题就是为了解决这样的问题,动态决议可以让我们实现动态地为类添加方法以避免未实现的方法调用。
动态方法决议
Object-C为我们提供了名为动态决议的手段,可以使我们在运行时动态地为一个selector添加实现。我们只要实现 +resolveInstanceMethod: 和/或 +resolveClassMethod: 方法,并在其中为指定的 selector 提供实现即可(通过调用运行时函数 class_addMethod 来添加)。这两个方法都是 NSObject 中的类方法,其原型为:
参数name表示动态决议的selector,返回值根据官方文档的说法,它的作用表示动态决议是否成功。
然后我们将代码修正如下:
程序将会正常运行,并输出: Out resolveInstanceMethod called say: 动态添加方法:Hello
从以上代码中我们可以看到,除了比较关键的resolveInstanceMethod外还有一个重要的函数为class_addMethod,它能在运行期动态地为 name 这个 selector 添加实现:funcyion。class_addMethod 是运行时函数,所以需要导入头文件:objc/runtime.h。 其函数原型如下: BOOL class_addMethod(Class cls,SEL name,IMP imp,const char* types); 调用 方法如下: class_addMethod([self class], name, (IMP)function, "v@:@"); 我们都知道每一个object-C方法的本质其实就是一个至少带有两个参数(self,_cmd)的普通C函数,因此在这个例子中笔者定义了一个say函数,从外部调用看,它只包含了一个NSString类型参数 在class_addMethod的4个参数中唯一让笔者一开始不太明白和是第四个参数,types,,查阅资料后得知其是一个定义该函数返回值类型和参数类型的字符串 本例中types参数为"i@:@“,按顺序分别表示: v : v表示返回值为void @ :参数id(self) : :SEL(_cmd)对象 @ :id(str)
一句话来说,type表明了该函数从左到右返回值及参数的类型,@表示object对象。:表示selector对象 其他类型如下:
|
IOS动态方法决议
最新推荐文章于 2023-03-20 20:35:43 发布