使用objective-c运行时将另一个替换为超类

时间:2017-11-30 22:55:33

标签: objective-c runtime

是否可以使用Objective-C运行时替换另一个类?

例如,我有一个“Parent”类,它是“ChildA”,“ChildB”,“ChildC”,“ChildD”类的父类。 我想在新类“NewChild”中覆盖在“Parent”中实现的方法,该类将是4个“Child *”类的父级。 我想用“NewChild”动态替换“Parent”,所以如果我使[ChildA new],我得到一个实例,它是“NewChild”的子类,它是“Parent”的子类。

是否可以使用obj-c运行时执行此操作?如果是的话,这样安全吗?

1 个答案:

答案 0 :(得分:1)

  

是否可以使用obj-c运行时执行此操作?如果是的话,这样安全吗?

简短答案:否,可能不是

说明:

从历史上看,似乎在短时间内,有一个运行时方法来设置类的超类,理论上它可以实现你所寻求的东西,但这一直是不仅被弃用而且被标记为"不要使用"。

即使您选择违反该警告并设法更改超级链,您也会进入" Here Be Dragons"。

成功的一个根本挑战是super次来电。标准方法调用基于对象的运行时类型和继承链。但是,super调用基于编译时中的方法所在的静态类。因此,虽然您可以 swizzle 方法 - 这涉及动态更改类,但是特定方法实现在运行时关联 - 如果这样的方法进行任何super调用,则那些方法相对于方法编译时间类。正如您稍后添加评论:

  

它位于已编译的库中,因此我只能使用运行时执行此操作。

然后尝试拼接,忽略"不要使用"警告,一个编译过的类,在你不知情的情况下可以在其中进行super次调用,可能会导致混乱。

出于同样的原因,如果您没有希望拼接的类的来源,那么使用方法调整来拼接方法的代码,没有搞乱继承链也存在风险。

如果您确实拥有希望拼接的方法的来源,并且知道它没有进行super次调用,那么您可以考虑调整 - 您需要考虑三种方法实现,{{1}中的方法},Parent中的方法,第三个你要写入调用NewChild,它负责在调用Parent之前从NewChild调用实现。< / p>

如果你真的希望走这条路,你需要研究一下是如何工作的(有很好的Q&amp; A&#39; s,但我有偏见;-))确保正确地将实现编织在一起。 建议您首先考虑针对您的应用设计不同的设计,并以不同的方式解决您的问题。记得搞乱运行时: Here Be Dragons

HTH