2011-06-30 17 views
6

以下將通過respondsToSelector測試,但SIGABRT[viewController selector][viewController action:selector]的實際調用。堆棧跟蹤狀態'NSInvalidArgumentException,原因: - [MyViewController選擇器]:無法識別的選擇器'。使用選擇器和NSSelectorFromString向對象發送消息

[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]; 
     } 
    } 
} 

回答

10
[self performSelector:@selector(notifyViewControllers:) withObject: message]; 
4

嘗試

[viewController performSelector:selector]; 

還要檢查其他方法NSObject的在performSelector「家庭」 - 他們可以方便地與延遲和/或在後臺線程調用選擇。

+0

感謝弗拉基米爾。拉克什擊敗你(performSelector) - 但你的確是正確的。 – jww

2

可能是有用的知道如何做到這一點,你不能使用performSelector,也許是因爲選擇字符串必須在協議方法中使用:

爲了使選擇支護參數,它應該被指定爲如下:

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

比方說,我們要處理的點按手勢

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

UIGestureRecognizer類允許使用識別器本身在操作回調:

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

所以做一些自來水真棒,我們可以這樣寫:

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