Ios respondsToSelector:不为委托工作
我是iOS世界的新手,在尝试将表视图中的值传递回主控制器时遇到问题 我正在研究的场景是Ios respondsToSelector:不为委托工作,ios,objective-c,ios5,respondstoselector,Ios,Objective C,Ios5,Respondstoselector,我是iOS世界的新手,在尝试将表视图中的值传递回主控制器时遇到问题 我正在研究的场景是 家庭控制器有一个按钮 单击“打开”按钮可打开第二个UIViewController中的项目列表 用户从列表中选择一项 所选项目将添加到主控制器上的另一个列表中 非常感谢对这个问题的任何建议: 这就是我在家准备赛格的方式 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UIViewController *des
- (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”返回true
现在,在SecondController中,当用户选择一个项目时,我调用didSelectRowAtIndexPath
&viewwilldiscover
方法设置该项目并使视图消失:
- (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
forsetSelection
返回false,即使我的HomeController中有setSelection方法:
- (void) setSelection:(NSDictionary *)dict {
if (![dict isEqual:selection]) {
......
}
}
如果我的问题不清楚或格式不正确,请提前道歉。顺便说一句,这是针对带有Xcode 4.2的iOS 5的,要让委派工作,您需要如下设置: 在
FirstViewController.h
头文件中,确保声明第二个视图控制器符合委派视图控制器的协议:
@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
您会注意到,您不应该在prepareforsgue
方法中使用UIViewController
,而应该将其强制转换为实际的视图控制器,以便设置该视图控制器的属性。这样,您就不必测试视图控制器是否响应,因为它要么定义了委托
属性,要么没有(在这种情况下,您需要添加一个)
要设置原始代理协议,通常在SecondViewController.h
文件中遵循以下格式:
- (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;
}
}
@protocol SecondViewControllerDelegate <NSObject>
- (void)setSelection:(NSDictionary *)dict;
@optional
- (void)someOptionalDelegateMethodHere;
@end
@interface SecondViewController : UIViewController
@property (nonatomic, weak) id <SecondViewControllerDelegate>delegate;
@end
由于
delegate
在.h文件中定义为公共属性,因此您可以将其引用为self.delegate
或\u delegate
,但将其引用为delegate
会使我认为您错误地将其定义为私有实例变量
大约只有当您没有正确地将该委托
分配给您的FirstViewController时,这种类型的模式才会对respondsToSelector:
做出响应
希望这有帮助 试试这个:
if ([destination respondsToSelector:@selector(setDelegate:)]) {
[destination performSelector:@selector(setDelegate:) withObject:self];
}
显示您如何在“主”视图控制器中声明委托。我可能在这里遗漏了一些内容,但我假设在应用程序启动时为我创建的委托是“自动”的。这就是我在“第二个”控制器中声明它的方式:@property(弱的,非原子的)id委托;如果您记录委托,它是非零的吗?为什么在这里使用键值编码(setValue:forKey:
),或者只使用If([destination respondsToSelector:@selector(setDelegate:)]){[destination setDelegate:self];}
@newacct-这不起作用,因为编译器不知道目标声明了选择器setDelegate,并且给出了错误没有可见的@interface for'UIViewController'声明了选择器“setDelegate:”
@newacct-如果他将目标声明为id
类型,则您的建议确实有效对于UIViewController*
“您可以将其引用为self.delegate或_delegate,但将其引用为delegate会使我认为您错误地将其定义为私有实例变量。”您假设他没有显式地将其合成。但如果他真的这么做了代码>,,然后,他确实可以将实例变量引用为delegate
@iwasrobed-无需检查该委托是否响应选择器setSelection:
,因为它必须响应,因为它实现了SecondViewControllerDelegate协议,并且该方法是必需的。@vacawama Xcode将警告您不要实现必需的委托方法,但仅此而已。您仍然可以编译和运行该程序,当它尝试调用该选择器时,它将失败。因此,除非您希望确保应用程序不会崩溃,否则“没有必要”。@iWasRobbed-使用警告构建是个坏主意。他们在那里是有原因的。我不确定投入额外的代码来避免我不注意它们是否值得。YMMV@vacawama也许你应该停止向唱诗班宣讲其他人的答案。。。如果你对一个问题有更好的答案,请回答。
if ([destination respondsToSelector:@selector(setDelegate:)]) {
[destination performSelector:@selector(setDelegate:) withObject:self];
}