代码之家  ›  专栏  ›  技术社区  ›  Wolfgang Schreurs

委托方法在声明为@optional时似乎是@required

  •  4
  • Wolfgang Schreurs  · 技术社区  · 16 年前

    我已经为ObjC类创建了自己的委托。类本身处理核心数据操作。委托方法用于将数据存储发生的更改通知其他类。处理数据存储的类称为datastore,它的委托称为DatastoreDelegate。我的UIViewController(ContactsViewController)实现委托。

    我的DatastoreDelegate声明如下:

    @class Datastore;
    @protocol DatastoreDelegate <NSObject>;
    @optional
    - (void)didAddMessage:(Message *)message;
    - (void)didUpdateContact:(Contact *)contact;
    - (void)didAddContact:(Contact *)contact;
    - (void)didUpdateContact:(Contact *)contact;
    - (void)didDeleteContacts;
    @end
    

    奇怪的是,除了[didAddMessage:]方法之外,我的代码在这些方法中都运行良好。每当我试图从Datastore类中调用此委托时,ContactsViewController就会出错。错误告诉我ContactsViewController实例中缺少[didAddMessage:]选择器(无法识别的选择器已发送到实例)。如果选择器是可选的,它怎么会丢失呢?

    我应该注意,我的数据存储类是一个单例。我不确定这是否与我的问题有关。

    2 回复  |  直到 16 年前
        1
  •  26
  •   Darren    16 年前

    “可选”表示调用方负责检查目标是否响应给定的选择器。例如。:

    if ([_myDelegate respondsToSelector:@selector(didAddMessage:)])
    {
        [_myDelegate didAddMessage:theMessage];
    }
    
        2
  •  4
  •   mipadi    16 年前

    你实施了吗 didAddMessage: ContactsViewController ? 它是可选的,因此您不会被迫实现它,但是如果您发送 didAddMessage: 接触器可视控制器 ,仍然会收到编译器警告。换句话说,, @optional 这只是意味着你不必实现它,但是如果你还没有实现它,但试图使用它,编译器可能会给出警告。

    你可能想做什么 Datastore 这是:

    if ([delegate respondsToSelector:@selector(didAddMessage:)]) {
        [delegate didAddMessage:theMessage];
    }
    

    [delegate didAddMessage:theMessage];
    

    (在第一个示例中,您仍然会得到一个编译器警告,但是可以安全地忽略它,因为您正在运行时检查是否在委托中实现了适当的方法。)