如果我希望我的班级有代表,我是否必须指定协议?

时间:2009-03-29 03:02:47

标签: iphone objective-c

我是Apple的平台上的Objective-C和开发的新手,但我希望无论如何都可以用一种可以理解的方式构建这个问题:)

我想解析我的iPhone应用程序的XML提要,我决定不将所有委托方法从NSXMLParser实例推送到我的视图控制器中,我将其包装在FeedParser类中。在阅读了一些文档和示例代码之后,这就是我想出的内容:

@protocol FeedParserDelegate <NSObject>

- (void)parserDidLoadEpisodes:(NSArray *)episodes;

@end


@interface FeedParser : NSObject {
    id <FeedParserDelegate> delegate;
}

@property (nonatomic, assign) id <FeedParserDelegate> delegate;

- (id)initWithURL:(NSURL *)url delegate:(id<FeedParserDelegate>)theDelegate;

@end

简单。我的FeedParser对象的代表只需要实现parserDidLoadEpisodes

但是,当我开始实际使FeedParser班级使用NSXMLParser时,我意识到我没有必要指定FeedParserNSXMLParser实施协议 - - 我可以实现我想要做的事情的委托方法。我想我已经注意到了跟随委托模式的其他类,但不是全部。

那么为什么我也不会为我的FeedParser类指定正式协议而烦恼呢?它会削减一些可能不必要的代码。我想问题是:为什么我想要创建一个正式的协议,而不仅仅是做一些事情,只是检查一下是否在respondsToSelector委托上实现了该方法?如果没有实现所需的委托方法,编译器是否会发出好警告?

3 个答案:

答案 0 :(得分:6)

@protocol声明的协议称为“正式协议”。另一种方法是在NSObject上声明一个类别(一组附加方法),如下所示:

@interface NSObject (FeedParserDelegate)

- (void)parserDidLoadEpisodes:(NSArray *)episodes;

@end

然后,只需为要作为提要解析器委托的任何对象定义该方法,否则将其保留为未定义。这被称为“非正式协议”。

为什么有两种方式?嗯,这是一个提示:非正式协议首先出现。它归结为他们添加了正式的协议,因为非正式的协议没有削减它。非正式协议使得很容易忘记一个重要的方法,或者试图将一个对象用作委托,而不是设计用于它的东西。

基本上,在这里和那里添加<FeedParserDelegate>的成本,您可以让编译器为您进行调试。编译器将为最常见的委托错误生成警告,如果您犯下其中一个错误,可以节省您的时间。为什么不利用它的帮助?

答案 1 :(得分:2)

总是,始终,总是喜欢在运行时进行编译时错误检查。你当然可以问班级是否支持这种方法,但为什么要问你何时可以知道呢?

答案是否定的,你不必。但是你应该想要。 :)

答案 2 :(得分:2)

添加协议会让编译器为您检查一些事情。如果你没有在编译时得到那些错误的错误,那么你将在运行时稍后更难以追踪它们。