如何在Objective-C中扩展协议/委托
如果我想扩展一个像AVAudioPlayer类,最好的方法是什么也添加另一个方法到AVAudioPlayerDelegate? 我是否为它做了一个分类,我扩展它吗? 如果我扩展它,那么我也必须确保覆盖实际的代理getter / setter? 我将如何扩展协议? 以下给我错误
@protocol AudioTrackDelegate : AVAudioPlayerDelegate { - (void)foo; } @end @interface AudioTrack : AVAudioPlayer { } @end
创build一个实现另一个协议的协议的语法是这样的:
@protocol NewProtocol <OldProtocol> - (void)foo; @end
如果你想在一个types为OldProtocol
的指针上调用NewProtocol
的方法,你可以调用respondsToSelector
:
if ([object respondsToSelector:@selector(foo)]) [(id)object foo];
或者将存根方法定义为NSObject
上的一个类别:
@interface NSObject (NewProtocol) - (void)foo; @end @implementation NSObject (NewProtocol) - (void)foo { } @end
记住一个协议不会向编译的应用程序添加代码 – 它只会强制实现这样一个事实,即您的类必须实现要被视为符合协议的方法。 一个很好的使用方法是使用所有相同的操作方式生成一组类: <printable>
或<serialized>
等,所以你可以创build一个<plays>
协议,例如:
@protocol plays - (void) play; - (NSString *) type; @end
然后一个符合<plays>
必须实现play
和type
方法。 如果没有,编译器会发出警告,但无论如何编译类。 在你的代码中,你检查一个对象是否符合下面的代码的协议:
if ([obj conformsTo: @protocol(plays)]) { [obj play]; }
一个类别实际上为你的类dynamic地添加了新的方法。 这些方法可以作为select器在运行时全局访问,并且可以通过@selector(foo)
和[object foo:bar];
的名称来调用[object foo:bar];
类别的目的是为类添加特殊的新代码,即使你没有该类的源代码。 可能有安全问题,你可以在类中创build内存泄漏等。
在你的情况也许,在一个单独的文件AVAudioPlayerDelegate_TrackOps.m
#import "AVAudioPlayerDelegate.h" @implementation AVAudioPlayerDelegate (TrackOps) - (NSObject *) foo { // do foo stuff; return bar; } @end
把它作为NSObject
一个类别,使所有的类都响应foo
。 Foo
可以是一个独立的方法Objc_perform_selector(@selector(foo))
。
底线:使用一个类别为类添加一个快速方法,用于实施方法实现的协议,以及专用于现有类(如添加成员variables或主要新function)的子类。 类别也可以用来覆盖一个或两个方法,当一个子类是不需要和想要的,但通常如果你想添加function的类你做一个子类。 有关此主题的更多示例,想法和其他一般信息,始终有Objective-C的Apple介绍