Skip to content

Instantly share code, notes, and snippets.

@zhangkn
Last active May 3, 2018 09:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhangkn/473dbdc08c094c21cbe824485362723f to your computer and use it in GitHub Desktop.
Save zhangkn/473dbdc08c094c21cbe824485362723f to your computer and use it in GitHub Desktop.
方法转发:崩溃之前会预留几个步骤
// 1
+(BOOL)resolveInstanceMethod:(SEL)sel{
// 添加实例方法并返回 YES 的一次机会,它随后会再次尝试发送消息
}
// 2
- (id)forwardingTargetForSelector:(SEL)aSelector{
// 返回可以处理 Selector 的对象
}
// 3
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
// 您需要实现它来创建 NSInvocation
}
- (void)forwardInvocation:(NSInvocation *)invocation {
// 在您所选择的目标上调用 Selector
[invocation invokeWithTarget:target];
}
// 第一步:
// 当调用了某个不存在的方法时,运行时首先会调用一个名为 resolveInstanceMethod 的类方法,
// 如果所调用的方法是类方法的话,则调用 resolveClassMethod。
// 这时候我们便有机会来添加方法了,即上面提到的利用运行时动态添加方法: <script src="https://gist.github.com/zhangkn/9a8464db30e597d9ebb5291070b403f1.js"></script>
// 第二步:
// 如果不想创建新方法的话,第一步返回了NO,
// 还有 forwardingTargetForSelector。可以直接返回需要调用方法的目标对象即可,之后这个对象就会调用 Selector。
// 第三步骤:forwardInvocation
// 略为复杂的 forwardInvocation。
// 如果您需要这么做,那么还需要实现 methodSignatureForSelector。
// 所有的调用过程都被封装到 NSInvocation 对象当中,之后你便可以使用特定的对象进行调用了。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment