委托方法似乎是@required,它被声明为@optional

时间:2010-01-30 19:27:34

标签: objective-c singleton delegates selector instance

我为ObjC类创建了自己的Delegate。该类本身处理核心数据操作。委托方法用于通知其他类有关数据存储区发生的更改。处理数据存储区的类称为数据存储区,它的委托称为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:]选择器(发送到实例的无法识别的选择器)。如果它是可选的,选择器如何丢失?

我应该注意我的Datastore类是Singleton。我不确定这是否与我遇到的这个问题有某种关系。

2 个答案:

答案 0 :(得分:24)

“可选”表示调用者负责检查目标是否响应给定的选择器。 E.g:

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

答案 1 :(得分:4)

您是否在didAddMessage:中实施了ContactsViewController?它是可选的,因此您不必强制实现它,但如果您将didAddMessage:消息发送到ContactsViewController但尚未在ContactsViewController中实际实现它,您仍将获得编译器警告。换句话说,@optional只是意味着你不必实现它,但是如果你没有实现它但是尝试使用它,编译器仍然会发出警告。

您在Datastore中可能想要做的是:

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

而不仅仅是:

[delegate didAddMessage:theMessage];

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