Отправка сообщения на объект с помощью селектора и NSSelectorFromString - PullRequest
6 голосов
/ 30 июня 2011

Следующее пройдет тест respondsToSelector, но SIGABRT при фактическом вызове на [viewController selector] или [viewController action:selector].Трассировка стека гласит: «NSInvalidArgumentException, причина: - [MyViewController selector]: нераспознанный селектор».

[viewController @selector(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];
        }
    }
}

Ответы [ 3 ]

10 голосов
/ 30 июня 2011
[self performSelector:@selector(notifyViewControllers:) withObject: message];
4 голосов
/ 30 июня 2011

Попробуйте

[viewController performSelector:selector];

Также проверьте другие методы NSObject в семействе executeSelector - с ними вы можете легко вызвать селектор с задержкой и / или в фоновом потоке.

2 голосов
/ 17 октября 2012

Может быть полезно знать, как это сделать, когда вы не можете использовать executeSelector, возможно, потому что строка селектора должна использоваться в методе протокола:

Чтобы разрешить селектору поддерживать параметры, он должен быть указанследующим образом:

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

Допустим, мы собираемся обработать жест касания

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

Класс UIGestureRecognizer позволяет использовать сам распознаватель в обратном вызове действия:

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

Чтобы сделать что-то потрясающее на Tap, мы могли бы написать:

- (void)doSomethingAwesome:(UITapGestureRecognizer *)tapGesture
{
    // gesture handling with UIGestureRecognizer availability
}
...