2013-04-26 37 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