不兼容的指针类型从'Class'分配给'id <AVAudioPlayerDelegate>'

mic*_*ino 10 warnings ios5

我有一个实用AVAudioPlayerDelegate协议的" 实用程序 "类.

这是我的Utility.h

@interface Utility : NSObject <AVAudioPlayerDelegate>
{
}
Run Code Online (Sandbox Code Playgroud)

这是它的对应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
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的iOS应用程序运行良好,但是在迁移到iOS5和XCode 4.2之后,编译器开始抛出此警告,位于以下audioPlayer.delegate = self;行:

Incompatible pointer types assigning to id <AVAudioPlayerDelegate> from 'Class'
Run Code Online (Sandbox Code Playgroud)

怎么我不能摆脱它?

rob*_*off 17

您已将方法声明为类方法,并且您尝试使用Class对象作为委托.但是您无法向Class对象添加协议.

您需要更改playAudioFromFileName:...为实例方法并创建Utility要用作委托的实例.也许你想拥有一个Utility由所有呼叫者共享的单个实例.这是Singleton模式,在Cocoa中很常见.你做这样的事情:

Utility.h

@interface Utility : NSObject <AVAudioPlayerDelegate>
+ (Utility *)sharedUtility;
@end
Run Code Online (Sandbox Code Playgroud)

Utility.m

@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
Run Code Online (Sandbox Code Playgroud)

用法

[[Utility sharedUtility] playAudioFromFileName:@"quack" ofType:"mp3" withPlayerFinishCallback:@selector(doneQuacking:) onObject:duck];
Run Code Online (Sandbox Code Playgroud)


Cœu*_*œur 7

当您不需要Class的实例时,只需手动获取警告:

audioPlayer.delegate = (id<AVAudioPlayerDelegate>)self;
Run Code Online (Sandbox Code Playgroud)

另一方面,请注意,如果您需要Delegate,则意味着您应该将Class的实例作为良好的编码实践而不是静态类.它可以很容易地成为一个单身人士:

static id _sharedInstance = nil;
+(instancetype)sharedInstance
{
    static dispatch_once_t p;
    dispatch_once(&p, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}
Run Code Online (Sandbox Code Playgroud)