我有一个“实用程序”类来实现 AVAudioPlayerDelegate 协议。
这是我的 Utility.h
@interface Utility : NSObject <AVAudioPlayerDelegate>
{
}
这是它的对应 Utility.m
@implementation Utility
static AVAudioPlayer *audioPlayer;
+ (void)playAudioFromFileName:(NSString *)name ofType:(NSString *)type withPlayerFinishCallback:(SEL)callback onObject:(id)callbackObject
{
...
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: [self getResourceURLForName:name ofType:type] error: nil];
audioPlayer.delegate = self; // this is the line that causes the Warning
...
}
我的iOS应用程序运行良好,但是在迁移到iOS5和XCode 4.2后,编译器开始抛出此警告,位于audioPlayer.delegate = self;
行:
Incompatible pointer types assigning to id <AVAudioPlayerDelegate> from 'Class'
我怎么能摆脱它?
答案 0 :(得分:16)
您已将方法声明为类方法,并且您尝试将Class对象用作委托。但是你无法向Class对象添加协议。
您需要将playAudioFromFileName:...
更改为实例方法,并创建Utility
的实例以用作委托。也许您希望所有呼叫者共享一个Utility
实例。这是Singleton模式,在Cocoa中很常见。你做这样的事情:
@interface Utility : NSObject <AVAudioPlayerDelegate>
+ (Utility *)sharedUtility;
@end
@implementation Utility
+ (Utility *)sharedUtility
{
static Utility *theUtility;
@synchronized(self) {
if (!theUtility)
theUtility = [[self alloc] init];
}
return theUtility;
}
- (void)playAudioFromFileName:(NSString *)name ofType:(NSString *)type withPlayerFinishCallback:(SEL)callback onObject:(id)callbackObject
{
...
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: [self getResourceURLForName:name ofType:type] error: nil];
audioPlayer.delegate = self;
...
}
@end
[[Utility sharedUtility] playAudioFromFileName:@"quack" ofType:"mp3" withPlayerFinishCallback:@selector(doneQuacking:) onObject:duck];
答案 1 :(得分:6)
如果您不需要Class的实例,只需手动获取警告:
audioPlayer.delegate = (id<AVAudioPlayerDelegate>)self;
另一方面,请注意,如果您需要Delegate,则意味着您应该将Class的实例作为良好的编码实践而不是静态类。它可以很容易地成为singleton:
static id _sharedInstance = nil;
+(instancetype)sharedInstance
{
static dispatch_once_t p;
dispatch_once(&p, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}