I have an object, and I want to list all the selectors to which it responds. It feels like this should be perfectly possible, but I'm having trouble finding the APIs.
7 Answers
This is a solution based on the runtime C functions:
class_copyMethodList returns a list of class methods given a Class object obtainable from an object.
#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 */

- 29,133
- 4
- 51
- 68
-
8This answer gives you the class methods. If you want the methods that the object responds to replace this line `Method * mlist = class_copyMethodList(object_getClass(t), &mc);` with this one `Method * mlist = class_copyMethodList(t, &mc);` – bugloaf May 01 '14 at 21:50
-
1@bugloaf how does your comment make sense? the signature of object_getClass expects a class variable? – abbood May 15 '15 at 16:33
-
@abbood What don't you understand about my comment? I just double-checked the documentation now, and I stand by my comment. `object_getClass` expects an object, and returns the class object, of which the argument is an instance. If `class_copyMethodList` is passed a class object, it will return class methods. If it is passed a regular object, it will return the methods on that object. – bugloaf May 16 '15 at 18:31
-
2@bugloaf On iOS 9 at least, it will segfault when passed a regular object. – oarfish Mar 07 '16 at 11:01
-
ha ha @bugloaf your should say that "My answer below will give you the class methods", but not "This answer gives you the class methods". haha, someone thinks as "this answer" is "the original answer", not your answer. – vietstone May 03 '16 at 14:30
-
@camdaochemgio But I did mean "the original answer". – bugloaf May 03 '16 at 23:36
I think usually you'll want to do that in the console, instead of cluttering your code with debug code. This is how you can do that while debugging in lldb:
(Assuming an object 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]))); }

- 5,215
- 2
- 31
- 24
-
Doesn't work in Xcode 9.3.1 - error: no matching function for call to 'class_copyMethodList' candidate function not viable: no known conversion from 'int *' to 'unsigned int * _Nullable' for 2nd argument – nbransby May 24 '18 at 19:02
This is also possible with 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]))]))
}
Output:
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>
Tested with the 6s simulator running iOS 9.2, Xcode Version 7.2 (7C68).

- 41,701
- 23
- 172
- 300
Taking inspiration from JAL's answer, in Swift you can do:
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 realization
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);

- 29,217
- 8
- 193
- 205
Something like this should work (just put it in the object you're curious about). For example if you have an object that's a delegate and want to know what 'hooks' are available this will print out messages to give you that clue:
-(BOOL) respondsToSelector:(SEL)aSelector {
printf("Selector: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
return [super respondsToSelector:aSelector];
}
Note that I discovered this in the iPhone Developer's Cookbook so I can't take credit! For example output I get from a UIViewController
that implements the protocols <UITableViewDelegate, UITableViewDataSource>
:
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.

- 2,336
- 5
- 31
- 40

- 4,093
- 5
- 44
- 54
-
AFAICS this doesn't jive. Where are the arguments supposed to be coming from? – nmr Jun 19 '12 at 18:24
-
3This will only list the selectors that are dynamically queried at runtime (as with Objective-C "informal protocols"), not all the selectors that the object responds to. – rvalue Jan 18 '13 at 05:28
If you want to also get the selectors for the super classes you can loop through like this:
Class c = [myObject class];
while (c != nil) {
int i = 0;
unsigned int mc = 0;
Method* mlist = class_copyMethodList(c, &mc);
NSLog(@"%d methods for %@", mc, c);
for(i = 0; i < mc; i++) {
const char* selName = sel_getName(method_getName(mlist[i]));
NSLog(@"Method #%d: %s", i, selName);
}
free(mlist);
c = [c superclass];
}

- 1,339
- 15
- 17