diz*_*izy 72 iphone objective-c
如果我想扩展像AVAudioPlayer这样的类,那么最好的方法是向AVAudioPlayerDelegate添加另一个方法吗?我是否为它做了一个类别,我是否扩展它?如果我扩展它,那么我还必须确保覆盖实际的委托getter/setter吗?我该如何扩展协议?以下是我的错误
@protocol AudioTrackDelegate : AVAudioPlayerDelegate {
- (void)foo;
}
@end
@interface AudioTrack : AVAudioPlayer {
}
@end
Run Code Online (Sandbox Code Playgroud)
rpe*_*ich 130
创建实现其他协议的协议的语法如下:
@protocol NewProtocol <OldProtocol>
- (void)foo;
@end
Run Code Online (Sandbox Code Playgroud)
如果你想调用一个NewProtocol
键入指针的方法,OldProtocol
你可以调用respondsToSelector
:
if ([object respondsToSelector:@selector(foo)])
[(id)object foo];
Run Code Online (Sandbox Code Playgroud)
或者将存根方法定义为以下类别NSObject
:
@interface NSObject (NewProtocol)
- (void)foo;
@end
@implementation NSObject (NewProtocol)
- (void)foo
{
}
@end
Run Code Online (Sandbox Code Playgroud)
小智 11
请记住,协议不会向已编译的应用程序添加任何代码 - 它只会强制您的类必须实现被视为"符合"协议的方法.很好地利用它可以生成一组具有相同操作方式的类:<printable>
或者<serialized>
等等.所以你可以创建一个<plays>
协议,例如:
@protocol plays
- (void) play;
- (NSString *) type;
@end
Run Code Online (Sandbox Code Playgroud)
然后一个符合<plays>
MUST 的类必须实现play
和type
方法.如果没有,编译器会发出警告,但无论如何都会编译该类.在您的代码中,使用以下代码检查对象是否符合协议:
if ([obj conformsTo: @protocol(plays)]) {
[obj play];
}
Run Code Online (Sandbox Code Playgroud)
类别实际上会为您的类动态添加新方法.运行时可以将这些方法作为选择器全局访问,并且可以通过名称调用,如@selector(foo)
和[object foo:bar];
类别的目的是为类添加特殊的新代码,即使您没有该类的源代码也是如此.可能存在安全问题,您可能会在类等中创建内存泄漏.
在您的情况下,也许在一个单独的文件中 AVAudioPlayerDelegate_TrackOps.m
#import "AVAudioPlayerDelegate.h"
@implementation AVAudioPlayerDelegate (TrackOps)
- (NSObject *) foo {
// do foo stuff;
return bar;
}
@end
Run Code Online (Sandbox Code Playgroud)
将它作为一个类别NSObject
使所有类都响应foo
.Foo
也可以是一个独立的方法 Objc_perform_selector(@selector(foo))
.
底线:使用类别向类添加快速方法,使用强制方法实现的协议,使用子类来专门化现有类(如添加成员变量或主要新功能).当不需要和需要子类时,类别也可用于覆盖一个或两个方法,但通常如果要为类创建子类添加功能.有关此主题的更多示例,想法和其他一般信息,Apple总是引入Objective-C
归档时间: |
|
查看次数: |
44335 次 |
最近记录: |