【问题标题】:Why is this delegate - protocol not responding?为什么这个委托 - 协议没有响应?
【发布时间】:2012-05-06 03:29:48
【问题描述】:

我有一个名为 dateSelectViewController 的方法在我的 .h 文件中声明为协议:

@class DateSelectViewController;
@protocol DateSelectViewControllerDelegate 

- (void)dateSelectViewController:(DateSelectViewController *)sender
                         theDate:(id)stringDate;

@end

在协议下方,我声明了一个委托:

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

在实现文件中,我合成了委托,并在我的视图中按下完成按钮时向委托发送消息:

- (IBAction)DonePressed:(id)sender {
    NSDate *chosen = [datePicker date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

    [formatter setDateFormat:@"MM/dd/yyyy"];
    NSString *formatedDate = [formatter stringFromDate:chosen];

    //sending a message to the delegate
    [self.delegate dateSelectViewController:self theDate:formatedDate];

    [self.navigationController popViewControllerAnimated:YES];
}

在被委派给的 .h 文件中,我正在导入委派者 .h 文件。在 .m 文件中我符合协议:

@interface MakePlantTVC ()<DateSelectViewControllerDelegate>
- (void)dateSelectViewController:(DateSelectViewController *)sender
                     theDate:(id)stringDate
{
    self.displayDate.text = stringDate;
    NSLog(@"delegate working");
}

由于某种原因,这完全有效。当在我的委托人类中按下完成按钮时,该按钮会按预期执行并弹出视图控制器,但就像消息永远不会发送给委托人一样。起初我以为我可以向 nil 发送消息,但它的类型为 id,所以情况不应该如此。为什么没有发送消息?

【问题讨论】:

  • 尝试在向代表发送消息之前添加NSLog(@"delegate = %@", self.delegate)
  • 你设置了代理吗?
  • 在将消息传递给委托人时,使用此条件检查委托人的可用性总是很好的if (self.delegate &amp;&amp; [self.delegate respondsToSelector:@selector(method_name)]) { [self.delegate method_name]}
  • @zrxq 我尝试了您的建议,并在向代表发送消息之前和之后添加了 NSLog,在这两种情况下我都收到 null。我不需要分配类型 ID,是吗?
  • 你会的。 id 是一个指向对象的指针。

标签: objective-c ios delegates protocols


【解决方案1】:

想到了一些事情

  • 您是否设置了委托?这听起来可能很愚蠢,但当委托人不工作时,90% 的情况是因为我忘记或丢失了 IB 连接。
  • 你的弱对象会过期吗?弱对象是 nil'ed - 因此您正在对“无”执行委托操作 - 也许您想要更多保留的东西或 NSNotification

我与代表一起练习的其他可能有用的事情

  • 使用基于断言的编程?当您拥有具有所需功能的协议时,值得断言,即:NSAssert(delegate, @"Error, delegate not set!");
  • 检查代理是否响应选择器
  • 使用 GCD 异步调度委托调用,即:

    dispatch_async(dispatch_get_main_queue(), ^{
      if ([delegate_ respondsToSelector:@selector(updateUI:)]) 
        [delegate_ updateUI:self];
    });
    

希望这会有所帮助!

【讨论】:

  • 嘿,马特,为什么用 GCD 异步调度委托调用很重要?在我的代码中,我有类似的内容:` [self.delegate numberPadView:self digitPressed:[[[sender titleLabel] text] intValue]];` 顺便说一句,一个必需的委托方法。我对此感到好奇,以及当我忘记实现适当的自定义委托方法时如何为我的自定义委托方法实现 NSAssert 消息。当我忘记实现自己所需的委托方法时,我想弹出一条花哨的消息。
  • 委托函数很可能会更新 UI。更新 UI 应该在主线程上完成。 UI 回调保证会在主线程上发生,但 KVO、NSNotification 和 NSUrlConnection 回调不会。委托目标不应该关心其调用者的线程政治。恕我直言,切换主线程并让委托方法在需要时实现它自己的后台切换是一种很好的做法。通过假设委托方法发生在主线程上,您可以避免在每个委托的公共方法中实现测试切换重新调用。
  • RE 花式弹窗:实现doesNotRecognizeSelector
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 2020-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多