目前swizzling
正在Objective-C中尝试方法,我有一个问题.我试图理解方法混合的正确方法,在网上研究后我偶然发现了这个NSHipster帖子:http://nshipster.com/method-swizzling/
在帖子中,作者有一些方法调整样本代码.我正在寻找有人能够更好地向我解释作者正在做什么.特别是我对didAddMethod
逻辑感到困惑.为什么作者不仅仅是直接的swapping/exchanging
方法实现?我唯一的理论是,可能还有一些机会viewWillAppear:
尚未加入UIViewController's method
dispatch_table
.特别是如果可能先将类别加载到内存中UIViewController
......这是为什么?看起来很奇怪?只是寻找更多洞察力/清晰度,谢谢:)
特别是我对didAddMethod逻辑感到困惑.为什么作者不只是直接交换/交换方法实现?
你的困惑是可以理解的,因为这个逻辑没有得到清楚的解释.
首先忽略这个例子是特定类的一个类别的事实,UIViewController
并且只考虑逻辑,好像类别在某个任意类上,让我们调用该类TargetClass
.
我们将调用我们希望替换的现有方法existingMethod
.
类别,正对TargetClass
,增加了交叉混合的方法,我们称之为swizzlingMethod
,对TargetClass
.
重要说明:请注意,获取方法的函数class_getInstanceMethod
将在提供的类或其任何超类中找到该方法.但是在功能class_addMethod
和class_replaceMethod
只添加/替换提供的类方法.
现在有两种情况需要考虑:
TargetClass
本身直接包含一个实现existingMethod
.这是一个简单的案例,所有需要做的就是交换和实现,existingMethod
并且swizzlingMethod
可以完成method_exchangeImplementations
.在文章中,调用class_addMethod
将失败,因为已经存在且existingMethod
直接存在 TargetClass
且逻辑导致调用method_exchangeImplementations
.
TargetClass
并不直接包含的实现existingMethod
,而是通过从继承的祖先类之一提供该方法TargetClass
.这是一个棘手的案例.如果你只是交换的实现existingMethod
和swizzlingMethod
那么你就可以实现(的情况下)的祖先类(和方式,也可能导致崩溃-这是为什么留作练习).通过调用class_addMethod
文章的代码是为了确保有一个existingMethod
在TargetClass
-它的实现是最初实现的swizzlingMethod
.然后逻辑将swizzlingMethod
祖先的实现替换为实现(对祖先existingMethod
没有影响).
还在?我希望这是有道理的,并不是简单地让你睁眼!
另一项运动,如果你是末期好奇:现在你可能会问,如果祖先发生了什么existingMethod
实现包含一个电话super
......如果实现,现在还附着swizzlingMethod
在TargetClass
那里将是呼吁super
结束?是祖先的实现,它会看到相同的方法实现执行两次,还是原始的祖先的祖先?
HTH