Anoide
Anoide

Reputation: 111

Passing class method as selector problem

I want to build a selector from a class method.

I'm doing it this way:

NavigationTreeActionHandler* handler=[NavigationTreeActionHandler self];
NavigationTreeNode* bombsNode=new NavigationTreeNode("Bombs","bigbomb.tif"
     ,handler,@selector(BigBombButtonPressed:));

I need to pass to NavigationTreeNode the target and the selector to the target method. I try to get the target using the self property of the class object (Don't know if htis is the correct way to do it). Then I get the selector for the class method I want to call on the class.

Everything compiles ok but it fails when I use:

[[handler class] instanceMethodSignatureForSelector:selector];

I get a nil and don't really know why... could anybody help please?

Upvotes: 3

Views: 1621

Answers (2)

user102008
user102008

Reputation: 31353

It's likely you're using code that assumes that calling the method class will get an object's class, and thus uses [[handler class] instanceMethodSignatureForSelector:selector] to get the method signature for the selector on the object handler. While that works for normal objects, that does not work for class objects, because of the different meaning of the class method on class objects, since the class method +class overrides the instance method -class, and +class simply returns the object it's called on, instead of the class it's an instance of (a meta-class).

The solution is that you don't even need to get the class at all, as there is a method you can call on an instance to get its method signature:

[handler methodSignatureForSelector:selector]

This is a much shorter and simpler way of doing what was intended, and also works for class objects too.

Upvotes: 1

David Gelhar
David Gelhar

Reputation: 27900

A few suggestions:

  • [NavigationTreeActionHandler self] will work fine to get the class object, but I would declare handler as type id instead of NavigationTreeActionHandler*, because it's not a reference to an instance that type

  • [handler class] is redundant; handler is already the class object.

  • instanceMethodSignatureForSelector: is only going to return nil if handler does not implement the selector. Verify your spelling etc., and try throwing in an NSLog to verify what you're receiving:

    NSLog("handler = %@ sel = %@", handler, NSStringFromSelector(selector));

But I'm unclear on what you're trying to do with instanceMethodSignatureForSelector: in the first place. If you're just trying to call the class method, wouldn't [handler performSelector:selector]; do what you want?

Upvotes: 3

Related Questions