我是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
时,我意识到我没有必要指定FeedParser
为NSXMLParser
实施协议 - - 我可以实现我想要做的事情的委托方法。我想我已经注意到了跟随委托模式的其他类,但不是全部。
那么为什么我也不会为我的FeedParser
类指定正式协议而烦恼呢?它会削减一些可能不必要的代码。我想问题是:为什么我想要创建一个正式的协议,而不仅仅是做一些事情,只是检查一下是否在respondsToSelector
委托上实现了该方法?如果没有实现所需的委托方法,编译器是否会发出好警告?
答案 0 :(得分:6)
用@protocol
声明的协议称为“正式协议”。另一种方法是在NSObject上声明一个类别(一组附加方法),如下所示:
@interface NSObject (FeedParserDelegate)
- (void)parserDidLoadEpisodes:(NSArray *)episodes;
@end
然后,只需为要作为提要解析器委托的任何对象定义该方法,否则将其保留为未定义。这被称为“非正式协议”。
为什么有两种方式?嗯,这是一个提示:非正式协议首先出现。它归结为他们添加了正式的协议,因为非正式的协议没有削减它。非正式协议使得很容易忘记一个重要的方法,或者试图将一个对象用作委托,而不是设计用于它的东西。
基本上,在这里和那里添加<FeedParserDelegate>
的成本,您可以让编译器为您进行调试。编译器将为最常见的委托错误生成警告,如果您犯下其中一个错误,可以节省您的时间。为什么不利用它的帮助?
答案 1 :(得分:2)
总是,始终,总是喜欢在运行时进行编译时错误检查。你当然可以问班级是否支持这种方法,但为什么要问你何时可以知道呢?
答案是否定的,你不必。但是你应该想要。 :)
答案 2 :(得分:2)
添加协议会让编译器为您检查一些事情。如果你没有在编译时得到那些错误的错误,那么你将在运行时稍后更难以追踪它们。