使用 objective-c 运行时将超类替换为另一个超类
Substituing superclass by another one using objective-c runtime
是否可以使用 Objective-C 运行时将 class 替换为另一个?
例如我有一个 class "Parent" 是 "ChildA", "ChildB", "ChildC", "ChildD" classes。
我想在新的 class "NewChild" 中覆盖 "Parent" 中实现的方法,它将成为 4 "Child*" class 的父级。
我想用 "NewChild" 动态替换 "Parent",所以如果我制作 [ChildA new],我得到一个实例,它是 "NewChild" 的子 class,它是一个子class 个 "Parent"。
是否可以使用 obj-c 运行时来执行此操作?如果可以,安全吗?
Is it possible to do this using obj-c runtime ? and if so, is it safe ?
简短回答:不,可能不会
解释:
从历史上看,似乎有一段很短的时间,有一个运行时方法来设置 class 的 superclass,这在理论上可以实现您所寻求的,但这已经很久了不仅被弃用而且被标记为 "do not use".
即使您选择违反该警告并设法更改超级class 链,您也正在进入 "Here Be Dragons" 的世界。
成功的一个基本挑战是 super
电话。标准方法调用基于对象的 runtime 类型和继承链。但是,super
调用是基于编译时 中的静态 class 方法 。因此,尽管您可以 swizzle 方法——这涉及动态更改 class 特定方法实现在运行时关联——如果这样的方法进行任何 super
调用那么这些是相对于方法编译时间 class。如您稍后在评论中添加:
It is in a library that is already compiled, so I can only do this using runtime.
然后尝试拼接,忽略 "Do Not Use" 警告,一个编译的 class,它可能在您不知情的情况下在其中调用 super
,很可能进入不同的继承链造成混乱。
同样的道理,如果你没有class的源码,你想拼接进来,然后用method swizzling拼接方法的代码,without 弄乱继承链,也是有风险的。
如果您确实有想要拼接的方法的源代码并且知道它不会进行 super
调用,那么您可以考虑调配——您需要考虑三个方法实现,[= 中的方法15=],NewChild
中的方法,第三个你会写到 Parent
中,它负责在调用 Parent
中的实现之前从 NewChild
中调用实现.
如果你真的想走这条路你需要研究调配是如何工作的(SO上有很好的问答,但我有偏见;-))以确保您正确地将实现编织在一起。 但是建议您首先考虑应用程序的不同设计并以不同的方式解决您的问题。搞乱运行时时请记住:Here Be Dragons!
HTH
是否可以使用 Objective-C 运行时将 class 替换为另一个?
例如我有一个 class "Parent" 是 "ChildA", "ChildB", "ChildC", "ChildD" classes。 我想在新的 class "NewChild" 中覆盖 "Parent" 中实现的方法,它将成为 4 "Child*" class 的父级。 我想用 "NewChild" 动态替换 "Parent",所以如果我制作 [ChildA new],我得到一个实例,它是 "NewChild" 的子 class,它是一个子class 个 "Parent"。
是否可以使用 obj-c 运行时来执行此操作?如果可以,安全吗?
Is it possible to do this using obj-c runtime ? and if so, is it safe ?
简短回答:不,可能不会
解释:
从历史上看,似乎有一段很短的时间,有一个运行时方法来设置 class 的 superclass,这在理论上可以实现您所寻求的,但这已经很久了不仅被弃用而且被标记为 "do not use".
即使您选择违反该警告并设法更改超级class 链,您也正在进入 "Here Be Dragons" 的世界。
成功的一个基本挑战是 super
电话。标准方法调用基于对象的 runtime 类型和继承链。但是,super
调用是基于编译时 中的静态 class 方法 。因此,尽管您可以 swizzle 方法——这涉及动态更改 class 特定方法实现在运行时关联——如果这样的方法进行任何 super
调用那么这些是相对于方法编译时间 class。如您稍后在评论中添加:
It is in a library that is already compiled, so I can only do this using runtime.
然后尝试拼接,忽略 "Do Not Use" 警告,一个编译的 class,它可能在您不知情的情况下在其中调用 super
,很可能进入不同的继承链造成混乱。
同样的道理,如果你没有class的源码,你想拼接进来,然后用method swizzling拼接方法的代码,without 弄乱继承链,也是有风险的。
如果您确实有想要拼接的方法的源代码并且知道它不会进行 super
调用,那么您可以考虑调配——您需要考虑三个方法实现,[= 中的方法15=],NewChild
中的方法,第三个你会写到 Parent
中,它负责在调用 Parent
中的实现之前从 NewChild
中调用实现.
如果你真的想走这条路你需要研究调配是如何工作的(SO上有很好的问答,但我有偏见;-))以确保您正确地将实现编织在一起。 但是建议您首先考虑应用程序的不同设计并以不同的方式解决您的问题。搞乱运行时时请记住:Here Be Dragons!
HTH