ios - respondsToSelector:不为委托(delegate)工作

标签 ios objective-c ios5 respondstoselector

我是 iOS 世界的新手,在尝试将值从 TableView 传回主 Controller 时遇到了问题。

我正在处理的场景是

  1. 家庭 Controller 有一个按钮
  2. 点击按钮打开第二个 UIViewController 中的项目列表
  3. 用户从列表中选择一个项目
  4. 所选项目已添加到家庭 Controller 上的另一个列表

非常感谢有关此问题的任何指示:

这就是我在家里准备 Segue 的方式

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

}

SecondController 有一个委托(delegate) ID,所以我假设委托(delegate)设置为“respondsToSelector”,对于“setDelegate”返回 true

现在,在 SecondController 中,当用户选择一个项目时,我调用 didSelectRowAtIndexPathviewWillDisappear 方法来设置项目并使 View 消失:

- (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 for setSelection 返回 false 即使我的 HomeController 中确实有 setSelection 方法:

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

如果我的问题不清楚或格式不正确,请提前致歉。顺便说一句,这是针对带有 Xcode 4.2 的 iOS 5

最佳答案

要使委派工作,您需要这样设置:

在你的FirstViewController.h头文件,确保你声明第二个 View Controller 符合委托(delegate) View Controller 的协议(protocol):

@interface FirstViewController : UIViewController <SecondViewControllerDelegate>

您可以看到委托(delegate)在 < > 内。 View Controller 头文件中的符号。如果该协议(protocol)中有必需的委托(delegate)方法,如果您没有在实现文件中定义它们,Xcode 将显示警告。

然后您在 FirstViewController.m 中定义了您的委托(delegate)方法文件:

- (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;
    }
}

您会注意到,而不是使用 UIViewControllerprepareForSegue方法,你应该将它转换为实际的 View Controller ,这样你就可以设置它的属性。这样,您就不必测试 View Controller 是否响应,因为它有一个 delegate。属性已定义或未定义(在这种情况下,您需要添加一个)。

要设置您的原始委托(delegate)协议(protocol),您通常在 SecondViewController.h 中遵循此格式文件:

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

@interface SecondViewController : UIViewController

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

@end

对于 ARC,委托(delegate)几乎总是弱定义的。

然后当你想通知SecondViewController.m中的代表时

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

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

delegate在 .h 文件中定义为公共(public)属性,您可以将其引用为 self.delegate_delegate但将其引用为 delegate让我觉得你错误地将它定义为私有(private)实例变量。

关于这种类型的模式唯一一次不会响应 respondsToSelector:是当您没有正确分配 delegate 时给你的FirstViewController

希望这对您有所帮助!

关于ios - respondsToSelector:不为委托(delegate)工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16245808/

相关文章:

objective-c - 当用户移动 NSWindows 时将其固定到位

ios - 如何检查用户是否在 Twitter 上关注您?

ios - 弃用开源库中的警告?

iphone - 我们可以使用 Objective C 创建一个 Web 服务吗

ios - 如何从 ios 中的应用程序中获取仅购买的产品 ID 列表?

ios - 无法为某些情况创建圆柱体 - Arkit

iOS自定义对象初始化错误

objective-c - 处理 iOS 中缺少 Twitter 的情况

iphone - 在 didSelectRowAtIndexPath 上关闭 UIPopoverController

ios - 在iPhone设备上部署kony应用程序