OC方法的懒加载

原文链接:https://www.jianshu.com/p/1c6b4887674b

提到懒加载,或许99%搞iOS开发的同学都会用过,众所周知,懒加载就是用到的时候再加载,通常我们都用作属性上面,通过self.xx来实现。那么OC方法的懒加载你听说过吗?用过吗?下面就是通过runtime来实现一下方法的懒加载,玩一下。

首先创建一个Person类,.h文件里面什么都不用写

 

ViewController中导入头文件开始玩

 

viewdidload方法中初始化person并调用person的eat方法,此时可以看到xcode编译警告eat方法,如果我们现在运行代码,就会crash,因为找不到这个方法,找到Person.m

 

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 是为类方法进行决议。

先简单运行一下代码,打印一下SEL看看方法是什么

 

可以清楚的看到就是之前调用的eat,接下来用动态方法决议手段来修改上面的代码:

解析:

这个函数里面有4个参数,我们打开帮助看看官方是怎么说的。

 

参数1,需要添加方法的类。[Pseron class]

参数2,需要添加的方法,就是参数sel,刚才NSLog过了,就是eat

参数3就比较复杂了,书面翻译是需要填入一个函数,而这个函数需要有两个参数一个是self,一个是_cmd。那么我们可以返回刚才的实现代码看一下,这里又get了一个知识点就是,所有的C语言的函数里面,都有这两个隐式参数,只要调用系统都会传递进来。然后继续看官方文档,class_addMethod([self class], @selector(resolveThisMethodDynamically), (IMP) myMethodIMP, "v@:"); 这是官方给出的调用方式。 可以看到,参数3是用(IMP)强转过的函数,所以参数3就是(IMP)eat

参数4,字面解释是描述该方法参数类型的字符数组。可能的值,看Objective-C Runtime Programming Guide > Type Encodings。因为函数必须至少有两个参数自_cmd,第二和第三个字符必须是"@:"(第一个字是返回类型)。打开文档,可以看到

 

官方文档

因为我们的eat返回值是void,所以使用"v",加上官方要求的值放在一起就是"v@:"。

接下来我们实现一下带参数的方法

[p performSelector:@selector(play:) withObject:@"王者荣耀"];

带参数的方法

我们在参数四字符串后面继续拼接参数就好。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值