objective-c - 如何确定父类(super class)私有(private)方法是否在 Objective-C 中被重写?

标签 objective-c cocoa inheritance

因为在 Objective-C 中,私有(private)方法并不是真正私有(private)的(方法调度机制不区分私有(private)方法和公共(public)方法),子类很容易覆盖父类(super class)的私有(private)方法(更多关于这个在 Cocoa Coding Guidelines )。

然而,要检测到这一点并不容易。我正在寻找可以帮助我解决此问题的现成工具。

这不能简单地是一个静态分析工具,因为接口(interface)中没有暴露私有(private)方法。该工具要么必须检查二进制文件,要么在运行时解决这个问题。根据我的说法,此工具必须执行类似于以下操作的操作:

  1. 通过检查 header 获取项目使用的每个类的所有公共(public)方法的列表,然后执行步骤 2 或步骤 3

  2. 通过检查二进制文件获取覆盖的私有(private)方法

    a) 读取应用程序二进制文件及其链接的所有动态库,以获取应用程序使用的每个类定义的所有方法的列表。

    b) 其中,步骤1中未找到的方法为私有(private)方法。

    c) 遍历类层次结构并找出覆盖父类(super class)私有(private)方法的子类

  3. 在运行时获取重写的私有(private)方法

    a) 运行应用

    b) 使用 Objective-C 运行时方法,我们可以获得为所有类定义的所有方法。

    c) 同样,在步骤 1 中未找到的方法是私有(private)方法

    d) 遍历类层次结构并找出覆盖父类(super class)私有(private)方法的子类

这并不总是有效——因为类和方法可以在运行时添加/删除,一些情况会被遗漏(最值得注意的是,NSManagedObject 子类,其中提供了核心数据属性的方法运行)。不过没关系,我愿意忍受这种限制。

我相信使用 libclang 很有可能实现这一目标、otoolnm 等目标文件检查工具,以及 Objective-C 运行时,但是是否有现成的工具可以完成所有这些工作?

注意:我不是在寻找缓解此问题的方法;如何检测这种情况。

最佳答案

您可以通过进入 Objective-C 运行时来执行此操作。

参见objc/runtime.h,即:

/** 
 * Describes the instance methods implemented by a class.
 * 
 * @param cls The class you want to inspect.
 * @param outCount On return, contains the length of the returned array. 
 *  If outCount is NULL, the length is not returned.
 * 
 * @return An array of pointers of type Method describing the instance methods 
 *  implemented by the class—any instance methods implemented by superclasses are not included. 
 *  The array contains *outCount pointers followed by a NULL terminator. You must free the array with free().
 * 
 *  If cls implements no instance methods, or cls is Nil, returns NULL and *outCount is 0.
 * 
 * @note To get the class methods of a class, use \c class_copyMethodList(object_getClass(cls), &count).
 * @note To get the implementations of methods that may be implemented by superclasses, 
 *  use \c class_getInstanceMethod or \c class_getClassMethod.
 */
OBJC_EXPORT Method *class_copyMethodList(Class cls, unsigned int *outCount) 
     __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

关于objective-c - 如何确定父类(super class)私有(private)方法是否在 Objective-C 中被重写?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22059393/

相关文章:

在沙盒模式下重新启动后找不到 iOS 7 应用收据

ios - customTableViewCell 不工作

iphone - 有没有办法在不进入 iPhone 设置的情况下停止应用程序通知?

cocoa - 更改 Cocoa 中的文本光标(插入符号)颜色?

c++ - 关键字 "virtual"是否传递给中间基类?

objective-c - Cocoa 中的 XML 模式绑定(bind)/对象模型框架

objective-c - 如何将键盘快捷键绑定(bind)到 cocoa 中的 nsbutton

cocoa - 如何以编程方式显示 NSSearchField 菜单?

C++ - 与非平凡类成员类型的 union ?

inheritance - Swagger 2.0 中的抽象父类