获取 Objective-C 类或实例的所有方法

发布于 2024-08-18 18:24:25 字数 82 浏览 9 评论 0原文

在 Objective-C 中,我可以测试给定的类或实例是否响应某些选择器。但是如何查询一个类或实例的所有方法或类的属性(例如所有方法或属性的列表)?

In Objective-C I can test whether a given class or instance responds to certain selectors. But how can query a class or instance for all its methods or properties of a class (e.g. a list of all methods or properties)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

So尛奶瓶 2024-08-25 18:24:25

除了 Buzzy 的答案之外,出于调试目的,您还可以使用 -[NSObject _methodDescription] 私有方法。

在 lldb:

(lldb) po [[UIApplication sharedApplication] _methodDescription]

或 code: 中,

@interface NSObject (Private)
- (NSString*)_methodDescription;
@end

// Somewhere in the code:
NSLog(@"%@", [objectToInspect performSelector:@selector(_methodDescription)]);

输出将如下所示:

<__NSArrayM: 0x7f9 ddc4359a0>:
in __NSArrayM:
    Class Methods:
        + (BOOL) automaticallyNotifiesObserversForKey:(id)arg1; (0x11503b510)
        + (id) allocWithZone:(_NSZone*)arg1; (0x11503b520)
        + (id) __new:::::(const id*)arg1; (0x114f0d700)
    Instance Methods:
        - (void) removeLastObject; (0x114f669a0)
        - (void) dealloc; (0x114f2a8f0)
        - (void) finalize; (0x11503b2c0)
        - (id) copyWithZone:(_NSZone*)arg1; (0x114f35500)
        - (unsigned long) count; (0x114f0d920)
        - (id) objectAtIndex:(unsigned long)arg1; (0x114f2a730)
        - (void) getObjects:(id*)arg1 range:(_NSRange)arg2; (0x114f35650)
        - (void) addObject:(id)arg1; (0x114f0d8e0)
        - (void) setObject:(id)arg1 atIndex:(unsigned long)arg2; (0x114f99680)
        - (void) insertObject:(id)arg1 atIndex:(unsigned long)arg2; (0x114f0d940)
        - (void) exchangeObjectAtIndex:(unsigned long)arg1 withObjectAtIndex:(unsigned long)arg2; (0x114f8bf80)
        ......
in NSMutableArray:
    Class Methods:
        + (id) copyNonRetainingArray; (0x11ee20178)
        + (id) nonRetainingArray; (0x11ee201e8)
        + (id) nonRetainingArray; (0x120475026)
        + (id) arrayWithCapacity:(unsigned long)arg1; (0x114f74280)
        ......

In addition to Buzzy's answer, for debugging purposes you may use the -[NSObject _methodDescription] private method.

Either in lldb:

(lldb) po [[UIApplication sharedApplication] _methodDescription]

or in code:

@interface NSObject (Private)
- (NSString*)_methodDescription;
@end

// Somewhere in the code:
NSLog(@"%@", [objectToInspect performSelector:@selector(_methodDescription)]);

Output will look as following:

<__NSArrayM: 0x7f9 ddc4359a0>:
in __NSArrayM:
    Class Methods:
        + (BOOL) automaticallyNotifiesObserversForKey:(id)arg1; (0x11503b510)
        + (id) allocWithZone:(_NSZone*)arg1; (0x11503b520)
        + (id) __new:::::(const id*)arg1; (0x114f0d700)
    Instance Methods:
        - (void) removeLastObject; (0x114f669a0)
        - (void) dealloc; (0x114f2a8f0)
        - (void) finalize; (0x11503b2c0)
        - (id) copyWithZone:(_NSZone*)arg1; (0x114f35500)
        - (unsigned long) count; (0x114f0d920)
        - (id) objectAtIndex:(unsigned long)arg1; (0x114f2a730)
        - (void) getObjects:(id*)arg1 range:(_NSRange)arg2; (0x114f35650)
        - (void) addObject:(id)arg1; (0x114f0d8e0)
        - (void) setObject:(id)arg1 atIndex:(unsigned long)arg2; (0x114f99680)
        - (void) insertObject:(id)arg1 atIndex:(unsigned long)arg2; (0x114f0d940)
        - (void) exchangeObjectAtIndex:(unsigned long)arg1 withObjectAtIndex:(unsigned long)arg2; (0x114f8bf80)
        ......
in NSMutableArray:
    Class Methods:
        + (id) copyNonRetainingArray; (0x11ee20178)
        + (id) nonRetainingArray; (0x11ee201e8)
        + (id) nonRetainingArray; (0x120475026)
        + (id) arrayWithCapacity:(unsigned long)arg1; (0x114f74280)
        ......
无妨# 2024-08-25 18:24:25

您可以执行此操作,并且在 https://developer.apple .com/library/mac/documentation/cocoa/Reference/ObjCRuntimeRef/index.html

要获取类的所有实例或类方法,您可以使用 class_copyMethodList 并迭代结果。示例:

 #import <objc/runtime.h>

/**
 *  Gets a list of all methods on a class (or metaclass)
 *  and dumps some properties of each
 *
 *  @param clz the class or metaclass to investigate
 */
void DumpObjcMethods(Class clz) {

    unsigned int methodCount = 0;
    Method *methods = class_copyMethodList(clz, &methodCount);

    printf("Found %d methods on '%s'\n", methodCount, class_getName(clz));

    for (unsigned int i = 0; i < methodCount; i++) {
        Method method = methods[i];

        printf("\t'%s' has method named '%s' of encoding '%s'\n",
               class_getName(clz),
               sel_getName(method_getName(method)),
               method_getTypeEncoding(method));

        /**
         *  Or do whatever you need here...
         */
    }

    free(methods);
}

您需要对此方法进行两次单独的调用。一个用于实例方法,另一个用于类方法:

/**
 *  This will dump all the instance methods
 */
DumpObjcMethods(yourClass);

在元类上调用相同的方法将为您提供所有类方法

/**
 *  Calling the same on the metaclass gives you
 *  the class methods
 */
DumpObjcMethods(object_getClass(yourClass) /* Metaclass */);

You can do this and it is extremely well documented at https://developer.apple.com/library/mac/documentation/cocoa/Reference/ObjCRuntimeRef/index.html

To fetch all the instance or class methods of a class, you may use class_copyMethodList and iterate over the results. An example:

 #import <objc/runtime.h>

/**
 *  Gets a list of all methods on a class (or metaclass)
 *  and dumps some properties of each
 *
 *  @param clz the class or metaclass to investigate
 */
void DumpObjcMethods(Class clz) {

    unsigned int methodCount = 0;
    Method *methods = class_copyMethodList(clz, &methodCount);

    printf("Found %d methods on '%s'\n", methodCount, class_getName(clz));

    for (unsigned int i = 0; i < methodCount; i++) {
        Method method = methods[i];

        printf("\t'%s' has method named '%s' of encoding '%s'\n",
               class_getName(clz),
               sel_getName(method_getName(method)),
               method_getTypeEncoding(method));

        /**
         *  Or do whatever you need here...
         */
    }

    free(methods);
}

You will need to make two separate calls to this method. One for the instance methods and another for the class methods:

/**
 *  This will dump all the instance methods
 */
DumpObjcMethods(yourClass);

Calling the same on the metaclass will give you all the class methods

/**
 *  Calling the same on the metaclass gives you
 *  the class methods
 */
DumpObjcMethods(object_getClass(yourClass) /* Metaclass */);
一个人的旅程 2024-08-25 18:24:25

您需要使用 Objective C 运行时方法,请参见此处: https://developer.apple .com/reference/objectivec/objective_c_runtime

You'll want to use the Objective C runtime methods, see here: https://developer.apple.com/reference/objectivec/objective_c_runtime

暮年 2024-08-25 18:24:25

这可以通过 objc_method_list 实现。为了枚举您的方法,您必须事先注册所有方法。

该过程很简单:声明函数后,您可以创建 objc_method 的实例并注册函数名称。然后将 objc_method 添加到 objc_method_list 中,最后将 objc_method_list 传递给 class_addMethods 。

以下是帮助您入门的链接:
http://theocacao.com/document.page/327

This is possible via objc_method_list. In order to enumerate your methods, you will have to register all your methods before hand.

The process is straight forward: after you've declared your function you can create an instance of objc_method and register the function name. Then add the objc_method to a objc_method_list and finally pass the objc_method_list to class_addMethods..

Here is a link to get you started:
http://theocacao.com/document.page/327

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文