如何在 Objective-C 中扩展协议/委托?

如果我想扩展类 AVAudioPlayer,什么是最好的方法也添加另一个方法到 AVAudioPlayerGenerate?

我应该为它建立一个类别,还是扩展它?

如果我扩展它,那么我还必须确保覆盖实际的委托 getter/setter 吗?我该怎么扩展协议?

下面的内容给我带来了错误

@protocol AudioTrackDelegate : AVAudioPlayerDelegate {
- (void)foo;
}
@end


@interface AudioTrack : AVAudioPlayer {
}
@end
48542 次浏览

创建实现另一个协议的协议的语法如下:

@protocol NewProtocol <OldProtocol>
- (void)foo;
@end

如果你想调用 NewProtocol中类型为 OldProtocol的指针上的方法,你可以调用 respondsToSelector:

if ([object respondsToSelector:@selector(foo)])
[(id)object foo];

或者在 NSObject上将存根方法定义为一个类别:

@interface NSObject (NewProtocol)
- (void)foo;
@end
@implementation NSObject (NewProtocol)
- (void)foo
{
}
@end

记住,协议不会向已编译的应用程序添加任何代码——它只是强制要求您的类必须实现被认为“符合”协议的方法。这种方法的一个好用途是生成一组操作方式完全相同的类: <printable><serialized>,等等。例如,你可以创建一个 <plays>协议:

@protocol plays
- (void) play;
- (NSString *) type;
@end

然后,符合 <plays>的类必须实现 playtype方法。如果没有,编译器会发出警告,但还是会编译该类。在您的代码中,您可以检查一个对象是否符合以下代码的协议:

if ([obj conformsTo: @protocol(plays)]) {
[obj play];
}

类别实际上会动态地将新方法添加到您的类中。这些方法作为选择器在运行时可以全局访问,并且可以像在 @selector(foo)[object foo:bar];中那样通过名称调用

类别的用途是向类别添加特殊的新代码,即使您没有该类别的源代码。可能存在安全问题,您可能会在类中创建内存泄漏等。

在您的情况下,也许,在一个单独的文件 AVAudioPlayerDelegate_TrackOps.m

#import "AVAudioPlayerDelegate.h"
@implementation AVAudioPlayerDelegate (TrackOps)


- (NSObject *) foo {
// do foo stuff;
return bar;
}


@end

将其作为 NSObject的一个类别,使所有类响应 fooFoo也可以是独立的方法 Objc_perform_selector(@selector(foo))

底线: 使用类别向类中添加快速方法和用于实施的协议 方法实现,以及专门化现有类的子类(比如添加成员变量或主要的新功能)。当不需要子类时,类别也可以用来重写一两个方法,但是通常如果你想向类中添加功能,你可以创建一个子类。关于这个主题的更多例子、想法和其他一般信息,总是有关于 Objective-C 的苹果介绍