2008-12-01 11 views
35

के लिए सूची चयनकर्ता मेरे पास एक ऑब्जेक्ट है, और मैं उन सभी चयनकर्ताओं को सूचीबद्ध करना चाहता हूं जिनके बारे में यह प्रतिक्रिया देता है। ऐसा लगता है कि यह पूरी तरह से संभव होना चाहिए, लेकिन मुझे एपीआई खोजने में परेशानी हो रही है।उद्देश्य-सी ऑब्जेक्ट

उत्तर

71

यह एक समाधान क्रम सी कार्यों के आधार पर है: उदाहरण के उत्पादन के लिए मैं एक 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 */ 
+8

यह उत्तर आपको कक्षा विधियों देता है। यदि आप इस विधि को बदलने के लिए ऑब्जेक्ट का जवाब देना चाहते हैं, तो विधि * mlist = class_copyMethodList (object_getClass (t), &mc); 'इस विधि के साथ 'विधि * mlist = class_copyMethodList (टी, &mc);' – bugloaf

+1

@bugloaf आपकी टिप्पणी कैसे समझती है ऑब्जेक्ट_get क्लास का हस्ताक्षर क्लास वैरिएबल की अपेक्षा करता है? – abbood

+0

@abbood मेरी टिप्पणी के बारे में आप क्या समझते हैं? मैंने अभी दस्तावेज़ों को दोबारा जांच लिया है, और मैं अपनी टिप्पणी से खड़ा हूं। 'object_getClass' किसी ऑब्जेक्ट की अपेक्षा करता है, और कक्षा लौटाता है ऑब्जेक्ट, जिसमें तर्क एक उदाहरण है। यदि 'class_copyMethodList' को क्लास ऑब्जेक्ट पास किया गया है, तो यह क्लास विधियों को वापस कर देगा। अगर यह एक नियमित ऑब्जेक्ट पास हो जाता है, तो वह उस ऑब्जेक्ट पर विधियों को वापस कर देगा। – bugloaf

1

ऐसा कुछ काम करना चाहिए (बस उस वस्तु में रखें जिसे आप उत्सुक हैं)। उदाहरण के लिए आप एक वस्तु एक प्रतिनिधि है कि है और पता है कि 'हुक' उपलब्ध हैं इस संदेशों आपको लगता है कि सुराग देने के लिए बाहर प्रिंट होगा चाहते हैं:

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

ध्यान दें कि मैं iPhone डेवलपर कुकबुक में यह पता चला तो मैं क्रेडिट नहीं ले सकता!

class_copyMethodList वर्ग के तरीकों की एक सूची एक से एक कक्षा वस्तु दिया प्राप्य रिटर्न:

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

+2

यह केवल उन चयनकर्ताओं को सूचीबद्ध करेगा जो रनटाइम पर गतिशील रूप से पूछे जाते हैं (उद्देश्य-सी "अनौपचारिक प्रोटोकॉल" के साथ), ऑब्जेक्ट का जवाब देने वाले सभी चयनकर्ता नहीं। – rvalue

25

मुझे लगता है कि आम तौर पर आपको बस इतना करना, कंसोल में है कि बजाय डिबग कोड के साथ अपने कोड को अव्यवस्थित के चाहता हूँ।

(एक वस्तु टी मानते हुए) यह स्विफ्ट के साथ भी संभव है

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> 
यह आपको लगता है कि जबकि lldb में डीबगिंग कैसे कर सकते हैं है

आईओएस 9.2, एक्सकोड संस्करण 7.2 (7 सी 68) चलाने वाले 6 एस सिम्युलेटर के साथ परीक्षण किया गया।

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]) }) 
    } 
} 
संबंधित मुद्दे