2008-12-01 114 views

回答

71

這是基於運行時的C函數的溶液:

class_copyMethodList返回從一個給定的一類對象獲得的類方法的列表例如輸出I從UIViewController實現該協議<UITableViewDelegate, UITableViewDataSource>得到目的。

#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 */ 
1

像這樣的東西應該可以工作(只要把它放在你好奇的物體中)。例如,如果你有一個對象,這是一個委託,想知道「掛鉤」可這是什麼會打印出消息,給你線索:

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

注意,我在iPhone開發的食譜發現了這個所以我不能信用!

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. 
+0

AFAICS這並不合拍。理由應該來自哪裏? – nmr 2012-06-19 18:24:30

+2

這隻會列出在運行時動態查詢的選擇器(與Objective-C「非正式協議」一樣),而不是所有對象響應的選擇器。 – rvalue 2013-01-18 05:28:55

25

我想通常你會想要做的是,在控制檯上,而不是用調試代碼弄亂你的代碼。這是你如何能做到這一點,而在LLDB調試:

(假設一個對象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]))); } 
3

這也可能與斯威夫特:

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]))])) 
} 

輸出:

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> 

使用運行iOS 9.2的Xs版本7.2(7C68)的6s模擬器進行測試。

0

以從JAL的回答靈感,在斯威夫特你可以這樣做:

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]) }) 
    } 
}