Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending message to object using selector and NSSelectorFromString

The following will pass the respondsToSelector test, but SIGABRT on the actual call to [viewController selector] or [viewController action:selector]. The stack trace states 'NSInvalidArgumentException, reason: -[MyViewController selector]: unrecognized selector'.

[viewController @selector(selector)] will cause a compile error (error: expected ':' before 'selector').

When the selector is hard coded, all works well.

How do I send a message to an object through a selector?

-(void) notifyViewControllers:(NSString*) message
{
    if(!message) return;

    SEL selector = NSSelectorFromString(message);
    if(!selector) return;

    NSArray* viewControllers = [self.tabBarController viewControllers];
    if(!viewControllers) return;

    for (UIViewController* viewController in viewControllers)
    {
        if(!viewController) continue;

        if ([viewController respondsToSelector:selector]) {
            // [viewController selector];
            [viewController action:selector];
        }
    }
}
like image 638
jww Avatar asked Jun 30 '11 08:06

jww


3 Answers

[self performSelector:@selector(notifyViewControllers:) withObject: message];
like image 144
Rakesh Bhatt Avatar answered Nov 15 '22 07:11

Rakesh Bhatt


Try

[viewController performSelector:selector];

Also check other methods NSObject in performSelector 'family' - with them you can easily call selector with delay and/or on background thread.

like image 30
Vladimir Avatar answered Nov 15 '22 08:11

Vladimir


Could be useful to know how to do this where you cannot use performSelector, maybe because the selector string must be used within a protocol method:

In order to allow the selector supporting parameters, it should be specified as follow:

NSString *stringForSelector = @"doSomethingAwesome:"; // notice the colon

Let's say we're going to handle a tap gesture

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:NSSelectorFromString(stringForSelector)];

UIGestureRecognizer class allow to use the recognizer itself in the action callback:

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer;

So to do something awesome on Tap, we could write:

- (void)doSomethingAwesome:(UITapGestureRecognizer *)tapGesture
{
    // gesture handling with UIGestureRecognizer availability
}
like image 32
brainondev Avatar answered Nov 15 '22 08:11

brainondev