如果我想扩展像AVAudioPlayer这样的类,那么最好的方法是向AVAudioPlayerDelegate添加另一个方法吗?我是否为它做了一个类别,我是否扩展它?如果我扩展它,那么我还必须确保覆盖实际的委托getter/setter吗?我该如何扩展协议?以下是我的错误
@protocol AudioTrackDelegate : AVAudioPlayerDelegate { - (void)foo; } @end @interface AudioTrack : AVAudioPlayer { } @end
rpetrich.. 130
创建实现其他协议的协议的语法如下:
@protocol NewProtocol- (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
协议没有方法,它有方法定义; 也就是说,它描述了一个类必须被视为"符合"所述协议的名称,参数和返回类型.通过你的评论/问题,我打赌你忘记在你的-setDelegate中调用[super setDelegate:value]: (10认同)
小智.. 11
请记住,协议不会向已编译的应用程序添加任何代码 - 它只会强制您的类必须实现被视为"符合"协议的方法.很好地利用它可以生成一组具有相同操作方式的类:
或者
等等.所以你可以创建一个
协议,例如:
@protocol plays - (void) play; - (NSString *) type; @end
然后一个符合
MUST 的类必须实现play
和type
方法.如果没有,编译器会发出警告,但无论如何都会编译该类.在您的代码中,使用以下代码检查对象是否符合协议:
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
使所有类都响应foo
.Foo
也可以是一个独立的方法 Objc_perform_selector(@selector(foo))
.
底线:使用类别向类添加快速方法,使用强制方法实现的协议,使用子类来专门化现有类(如添加成员变量或主要新功能).当不需要和需要子类时,类别也可用于覆盖一个或两个方法,但通常如果要为类创建子类添加功能.有关此主题的更多示例,想法和其他一般信息,Apple总是引入Objective-C
创建实现其他协议的协议的语法如下:
@protocol NewProtocol- (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
请记住,协议不会向已编译的应用程序添加任何代码 - 它只会强制您的类必须实现被视为"符合"协议的方法.很好地利用它可以生成一组具有相同操作方式的类:
或者
等等.所以你可以创建一个
协议,例如:
@protocol plays - (void) play; - (NSString *) type; @end
然后一个符合
MUST 的类必须实现play
和type
方法.如果没有,编译器会发出警告,但无论如何都会编译该类.在您的代码中,使用以下代码检查对象是否符合协议:
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
使所有类都响应foo
.Foo
也可以是一个独立的方法 Objc_perform_selector(@selector(foo))
.
底线:使用类别向类添加快速方法,使用强制方法实现的协议,使用子类来专门化现有类(如添加成员变量或主要新功能).当不需要和需要子类时,类别也可用于覆盖一个或两个方法,但通常如果要为类创建子类添加功能.有关此主题的更多示例,想法和其他一般信息,Apple总是引入Objective-C