首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >respondsToSelector:不为委托工作

respondsToSelector:不为委托工作
EN

Stack Overflow用户
提问于 2013-04-26 21:54:20
回答 2查看 17.4K关注 0票数 4

我是iOS世界的新手,在尝试将一个值从TableView传递回主控制器时遇到了一个问题。

我正在研究的场景是

  1. 家庭控制器有一个按钮
  2. 单击按钮将打开第二个UIViewController中的项目列表
  3. 用户从列表中选择项。
  4. 选择的项被添加到主控制器上的另一个列表中

非常感谢任何关于这个问题的建议:

这就是我准备回家赛格的方式

代码语言:javascript
复制
- (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 & viewWillDisappear方法来设置该项并使视图消失:

代码语言:javascript
复制
- (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方法:

代码语言:javascript
复制
- (void) setSelection:(NSDictionary *)dict {
    if (![dict isEqual:selection]) {
        ......
    }
}

如果我的问题不清楚或没有很好的格式化,请提前道歉。顺便说一句,这是iOS 5的Xcode 4.2

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-26 22:37:15

为了使授权工作,您需要这样设置它:

在您的FirstViewController.h头文件中,确保您声明第二个视图控制器符合委托视图控制器的协议:

代码语言:javascript
复制
@interface FirstViewController : UIViewController <SecondViewControllerDelegate>

您可以看到委托在视图控制器的头文件中的< >符号中。如果该协议中存在必需的委托方法,则如果没有在实现文件中定义这些方法,Xcode将显示警告。

然后在FirstViewController.m文件中定义委托方法:

代码语言:javascript
复制
- (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;
    }
}

您将注意到,与其在UIViewController方法中使用prepareForSegue,不如将其转换为实际的视图控制器,这样就可以设置属性了。这样,您就不必测试视图控制器是否响应,因为它要么已经定义了delegate属性,要么没有(在这种情况下,您需要添加一个)。

要设置原始委托协议,通常在SecondViewController.h文件中遵循以下格式:

代码语言:javascript
复制
@protocol SecondViewControllerDelegate <NSObject>
- (void)setSelection:(NSDictionary *)dict;
@optional
- (void)someOptionalDelegateMethodHere;
@end

@interface SecondViewController : UIViewController

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

@end

对于ARC,代表的定义几乎总是很弱。

然后,当您想在SecondViewController.m中通知委托时

代码语言:javascript
复制
- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 

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

由于delegate被定义为.h文件中的公共属性,因此可以将其引用为self.delegate_delegate,但将其引用为delegate使我认为您将其错误地定义为私有实例变量。

只有当您没有正确地将该respondsToSelector:分配给您的FirstViewController时,这种类型的模式才不会对FirstViewController作出响应

希望这能有所帮助!

票数 10
EN

Stack Overflow用户

发布于 2013-04-26 22:37:47

试试这个:

代码语言:javascript
复制
if ([destination respondsToSelector:@selector(setDelegate:)]) { 
    [destination performSelector:@selector(setDelegate:) withObject:self];
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16245808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档