代码之家  ›  专栏  ›  技术社区  ›  Georg Fritzsche

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

  •  35
  • Georg Fritzsche  · 技术社区  · 14 年前

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

    4 回复  |  直到 5 年前
        1
  •  9
  •   Borys Verebskyi    7 年前

    您将要使用目标C运行时方法,请参见以下内容: https://developer.apple.com/reference/objectivec/objective_c_runtime

        2
  •  36
  •   Buzzy    9 年前

    您可以这样做,并且在 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 */);
    
        3
  •  31
  •   Borys Verebskyi    7 年前

    除了时髦的回答。出于调试目的,您可以使用 -[NSObject _methodDescription] 私有方法。

    在LLDB中:

    (lldb) po [[UIApplication sharedApplication] _methodDescription]
    

    或在代码中:

    @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)
            ......
    
        4
  •  4
  •   user250120    14 年前

    这可以通过objc_方法_列表实现。为了枚举您的方法,您必须在手前注册所有方法。

    这个过程是直接进行的:在您声明了您的函数之后,您可以创建一个objc_方法的实例并注册函数名。然后将objc_方法添加到objc_方法_列表中,最后将objc_方法_列表传递到类_addmethods。

    这里有一个链接可以让您开始: http://theocacao.com/document.page/327