如何在 Objective-C 中扩展协议/委托
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/732701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extend protocols / delegates in Objective-C
提问by dizy
If i want to extend a class like AVAudioPlayer, whats the best way to also add another method to AVAudioPlayerDelegate ?. Do I make a category for it, do I extend it? If I extend it do I then also have to make sure to overwrite the actual delegate getter/setter ? How would I extend the protocol ? The following gives me errors
如果我想扩展像 AVAudioPlayer 这样的类,那么将另一个方法添加到 AVAudioPlayerDelegate 的最佳方法是什么?。我是否为它创建一个类别,我是否扩展它?如果我扩展它,那么我还必须确保覆盖实际的委托 getter/setter 吗?我将如何扩展协议?以下给了我错误
@protocol AudioTrackDelegate : AVAudioPlayerDelegate {
- (void)foo;
}
@end
@interface AudioTrack : AVAudioPlayer {
}
@end
回答by rpetrich
The syntax for creating a protocol that implements another protocol is as such:
创建实现另一个协议的协议的语法如下:
@protocol NewProtocol <OldProtocol>
- (void)foo;
@end
If you want to call a method in NewProtocolon a pointer typed as OldProtocolyou can either call respondsToSelector:
如果您想在NewProtocol键入的指针上调用方法,OldProtocol您可以调用respondsToSelector:
if ([object respondsToSelector:@selector(foo)])
[(id)object foo];
Or define stub methods as a category on NSObject:
或者将存根方法定义为 上的类别NSObject:
@interface NSObject (NewProtocol)
- (void)foo;
@end
@implementation NSObject (NewProtocol)
- (void)foo
{
}
@end
回答by dizy
Remember a protocol adds no code to the compiled app -- it only enforces the fact that your class must implement the methods to be considered "conforming" to the protocol. A good use of this would be to generate a group of classes with all the same way of operating: <printable>or <serialized>, etc. So you could create a <plays>protocol for instance:
请记住,协议不会向已编译的应用程序添加任何代码——它仅强制您的类必须实现被视为“符合”协议的方法这一事实。一个很好的用途是生成一组具有相同操作方式的类:<printable>or<serialized>等。因此您可以创建一个<plays>协议,例如:
@protocol plays
- (void) play;
- (NSString *) type;
@end
And then a class that conforms to <plays>MUST implement the playand typemethods. If it doesn't, the compiler issues a warning but compiles the class anyway. In your code you check if an object does conform to a protocol with the following code:
然后符合的类<plays>必须实现play和type方法。如果没有,编译器会发出警告,但无论如何都会编译该类。在您的代码中,您可以使用以下代码检查对象是否符合协议:
if ([obj conformsTo: @protocol(plays)]) {
[obj play];
}
A category actually adds new methods dynamically to your class. These methods are globally accessible to the runtime as selectors and can be called by name as in @selector(foo)and [object foo:bar];
类别实际上是动态地向您的类添加新方法。这些方法可以作为选择器在运行时全局访问,并且可以通过名称调用,如 in@selector(foo)和[object foo:bar];
The purpose of a category is to add special new code to a class even if you don't have the source code for that class. There may be security problems and you could create memory leaks in classes, etc.
类别的目的是向类添加特殊的新代码,即使您没有该类的源代码。可能存在安全问题,您可能会在类中造成内存泄漏等。
In your case maybe, in a separate file AVAudioPlayerDelegate_TrackOps.m
在你的情况下,在一个单独的文件中 AVAudioPlayerDelegate_TrackOps.m
#import "AVAudioPlayerDelegate.h"
@implementation AVAudioPlayerDelegate (TrackOps)
- (NSObject *) foo {
// do foo stuff;
return bar;
}
@end
Putting it as a category of NSObjectmakes all classes respond to foo. Foocan be a stand alone method Objc_perform_selector(@selector(foo))as well.
将其作为 的类别NSObject使所有类都响应foo. Foo也可以是一种独立的方法 Objc_perform_selector(@selector(foo))。
Bottom Line: use a category to add a quick method to a class, protocols for enforcing method implementations, and subclasses to specialize existing classes (things like adding member variables or major new functionality). Categories can also be used to override a method or two when a subclass is not needed and wanted, but usually if you want to add functionality to a class you make a subclass. For more examples, ideas, other general information on this topic, there's always the Apple introduction to Objective-C
底线:使用类别向类添加快速方法,使用协议强制方法实现,以及使用子类专门化现有类(例如添加成员变量或主要新功能)。当不需要和想要子类时,类别也可用于覆盖一两个方法,但通常如果您想向类添加功能,则可以创建子类。有关此主题的更多示例、想法和其他一般信息,请参阅Apple 对 Objective-C 的介绍

