2013-04-26 95 views
4

我是iOS新手,遇到問題時嘗試將值從TableView傳回到主控制器。respondsToSelector:不適用於委託

,我的工作對這種情況的出現

  1. 家庭控制器上有一個按鈕
  2. 點擊按鈕,打開第二UIViewController中的項目清單
  3. 用戶從列表
  4. 選擇一個項目選定的項目被添加到家庭控制器上的另一個列表

真的很感謝任何指針,這是蘇:

這是我正在準備Segue公司家用

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    UIViewController *destination = segue.destinationViewController; 
    if ([destination respondsToSelector:@selector(setDelegate:)]) { 
     [destination setValue:self forKey:@"delegate"]; 
    } 

} 

SecondController有代表的ID,所以我假設委託設置爲「respondsToSelector」返回「setDelegate」

現在,SecondController當用戶選擇一個項目我打電話didSelectRowAtIndexPath & viewWillDisappear方法來設置項目,使視野中消失:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    POSAllItemsCell *cell = (POSAllItemsCell *) [tableView cellForRowAtIndexPath:indexPath]; 

    item = [NSDictionary dictionaryWithObjectsAndKeys:cell.name, @"Name", cell.price, @"Price", cell.code, @"Code", nil]; 

    [self dismissViewControllerAnimated:YES completion:NULL]; 

} 

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 

    if ([delegate respondsToSelector:@selector(setSelection:)]) { 
     [delegate setValue:item forKey:@"selection"]; 
    } 
} 

現在,這裏的問題是,對於respondsToSelector回報setSelection虛假的,即使我有我的HomeController爲setSelection方法:提前

- (void) setSelection:(NSDictionary *)dict { 
    if (![dict isEqual:selection]) { 
     ...... 
    } 
} 

道歉,如果我在不清晰的問題,或者格式不正確。順便說一句,這是爲iOS 5和Xcode 4.2

+0

顯示你如何宣佈「家」視圖控制器的委託。 – omz 2013-04-26 21:59:14

+0

嗯,我可能在這裏錯過了一些東西,但我認爲在應用程序啓動時爲我創建了代理「自動」。這是我如何在「第二個」控制器中聲明的:@property(weak,nonatomic)id delegate; – Vivek 2013-04-26 22:04:27

+0

如果您登錄委託,它是否爲零? – rdelmar 2013-04-26 22:05:09

回答

10

來委派工作,你需要設置它是這樣的:

在你FirstViewController.h頭文件,確保您宣佈第二視圖控制器符合委派視圖控制器的協議:

@interface FirstViewController : UIViewController <SecondViewControllerDelegate> 

你可以看到,委託去在視圖控制器的頭文件< >符號中。如果在該協議中需要委託方法,如果您沒有在實現文件中定義它們,Xcode將顯示警告。

- (void)setSelection:(NSDictionary *)dict { 
    if (![dict isEqual:selection]) { 
     ...... 
    } 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"someSequeIdentifierHere"]) { 
     SecondViewController *sv = segue.destinationViewController; 
     sv.delegate = self; 
    } 
} 

你會發現,而不是在prepareForSegue方法使用UIViewController,你應該只將它轉換爲實際的視圖控制器,以便您可以:

然後你在FirstViewController.m文件中定義的委託方法設置屬性。這樣,您不必測試視圖控制器是否響應,因爲它具有定義的delegate屬性,或者它不(在這種情況下,您需要添加一個)。

要設置你的原來的委託協議時,通常跟隨你SecondViewController.h文件格式:

@protocol SecondViewControllerDelegate <NSObject> 
- (void)setSelection:(NSDictionary *)dict; 
@optional 
- (void)someOptionalDelegateMethodHere; 
@end 

@interface SecondViewController : UIViewController 

@property (nonatomic, weak) id <SecondViewControllerDelegate>delegate; 

@end 

代表應該總是對弧弱定義。

然後,當你要通知委託在SecondViewController.m

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 

    if ([self.delegate respondsToSelector:@selector(setSelection:)]) { 
     [self.delegate setSelection:item]; 
    } 
} 

由於delegate被定義爲.h文件一個公共屬性,你可以參考它無論是作爲self.delegate_delegate但引用它作爲delegate品牌我認爲你錯誤地將其定義爲私有實例變量。

關於唯一一次這種類型的模式將不respondsToSelector:迴應是,當你不正確地分配一個delegateFirstViewController

希望這有助於!

+0

「您可以將其引用爲self.delegate或_delegate,但將其引用爲委託會讓我認爲您錯誤地將其定義爲私有實例變量。」你假設他沒有明確地「@綜合」它。但是如果他做了@synthesize委託,那麼他確實可以將實例變量稱爲委託。 – newacct 2013-04-27 03:11:19

+0

@iWasRobbed - 不需要檢查委託是否響應選擇器'setSelection:',因爲它必須執行SecondViewControllerDelegate協議,並且該方法是必需的。 – vacawama 2013-04-27 04:20:53

+0

@vacawama Xcode會警告你沒有實現所需的委託方法,但就是這樣。您仍然可以編譯並運行該程序,並在嘗試調用該選擇器時失敗。所以它是「沒有必要」,除非你想確保不會崩潰的應用程序。 – iwasrobbed 2013-04-27 13:59:59

0

試試這個:

if ([destination respondsToSelector:@selector(setDelegate:)]) { 
    [destination performSelector:@selector(setDelegate:) withObject:self]; 
} 
+0

或只是'if([destination respondsToSelector:@selector(setDelegate :)]){ [destination setDelegate:self]; }' – newacct 2013-04-27 03:07:49

+0

@newacct - 這不起作用,因爲編譯器不知道目標聲明瞭選擇器setDelegate並給出錯誤'UIViewController沒有可見的@interface'聲明選擇器'setDelegate:'' – vacawama 2013-04-27 03:57:04

+0

@newacct - 你的建議確實有效,但如果他聲明目的地是'id'而不是'UIViewController *'類型。 – vacawama 2013-04-27 04:09:46