我为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。我不确定这是否与我遇到的这个问题有某种关系。
答案 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];
(在第一个示例中,您仍然会收到编译器警告,但是可以安全地忽略,因为您在运行时检查是否在委托中实现了相应的方法。)