Frage

Ich habe ein Objekt, und ich möchte alle Wähler aufzulisten, auf die sie reagiert. Es fühlt sich an wie sollte dies durchaus möglich sein, aber ich habe Probleme, den APIs zu finden.

War es hilfreich?

Lösung

Dies ist eine Lösung auf den Runtime-C-Funktionen basiert:

class_copyMethodList gibt eine Liste von Klassenmethoden eines Class-Objekt, die aus einem Objekt gegeben.

#import <objc/runtime.h>

[..]

SomeClass * t = [[SomeClass alloc] init];

int i=0;
unsigned int mc = 0;
Method * mlist = class_copyMethodList(object_getClass(t), &mc);
NSLog(@"%d methods", mc);
for(i=0;i<mc;i++)
    NSLog(@"Method no #%d: %s", i, sel_getName(method_getName(mlist[i])));

/* note mlist needs to be freed */

Andere Tipps

Ich denke, in der Regel sollten Sie, dass in der Konsole zu tun, anstatt Ihren Code mit Debug-Code von unübersichtlich. Dies ist, wie Sie tun können, dass beim Debuggen in LLDB:

(Unter der Annahme eines Objekts t)

p int $num = 0;
expr Method *$m = (Method *)class_copyMethodList((Class)object_getClass(t), &$num);
expr for(int i=0;i<$num;i++) { (void)NSLog(@"%s",(char *)sel_getName((SEL)method_getName($m[i]))); }

Dies ist auch möglich, mit Swift:

let obj = NSObject()

var mc: UInt32 = 0
let mcPointer = withUnsafeMutablePointer(&mc, { $0 })
let mlist = class_copyMethodList(object_getClass(obj), mcPointer)

print("\(mc) methods")

for i in 0...Int(mc) {
    print(String(format: "Method #%d: %s", arguments: [i, sel_getName(method_getName(mlist[i]))]))
}

Ausgabe:

251 methods
Method #0: hashValue
Method #1: postNotificationWithDescription:
Method #2: okToNotifyFromThisThread
Method #3: fromNotifySafeThreadPerformSelector:withObject:
Method #4: allowSafePerformSelector
Method #5: disallowSafePerformSelector
...
Method #247: isProxy
Method #248: isMemberOfClass:
Method #249: superclass
Method #250: isFault
Method #251: <null selector>

Test mit dem Simulator 6s mit iOS 9.2, Xcode Version 7.2 (7C68).

So etwas sollte funktionieren (legt du es einfach in dem Objekt Sie neugierig auf). Wenn Sie zum Beispiel haben ein Objekt, das ein Delegierter ist und wollen wissen, was ‚Haken‘ verfügbar ist diese Meldungen auszudrucken werden Ihnen die Schlüssel zu geben:

-(BOOL) respondsToSelector:(SEL)aSelector {
    printf("Selector: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
    return [super respondsToSelector:aSelector];
}

Beachten Sie, dass ich dies in dem entdeckt iPhone Developer Kochbuch , so kann ich Kredit nicht nehmen! Zum Beispiel Ausgabe erhalte ich von einem UIViewController, die die Protokolle <UITableViewDelegate, UITableViewDataSource> implementiert:

Selector: tableView:numberOfRowsInSection:
Selector: tableView:cellForRowAtIndexPath:
Selector: numberOfSectionsInTableView:
Selector: tableView:titleForHeaderInSection:
Selector: tableView:titleForFooterInSection:
Selector: tableView:commitEditingStyle:forRowAtIndexPath:
Selector: sectionIndexTitlesForTableView:
Selector: tableView:sectionForSectionIndexTitle:atIndex:
...
...
etc.,etc.

Inspiriert von JAL 's Antwort, in Swift können Sie tun:

extension NSObject {
    var __methods: [Selector] {
        var methodCount: UInt32 = 0
        guard
            let methodList = class_copyMethodList(type(of: self), &methodCount),
            methodCount != 0
        else { return [] }
        return (0 ..< Int(methodCount))
            .flatMap({ method_getName(methodList[$0]) })
    }
}

ARC Realisierung

SomeClass *someClass = [[SomeClass alloc] init];    

//List of all methods
unsigned int amountMethod = 0;
Method *methods = class_copyMethodList(someClass, &amountMethod);

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

    printf("\t method named:'%s' \n", sel_getName(method_getName(method)));
}

free(methods);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top