Несовместимые типы указателей, присвоенные «id <AVAudioPlayerDelegate>» из «Class» - PullRequest
10 голосов
/ 29 октября 2011

У меня есть класс " Utility ", который реализует протокол 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'

Как я могу от нее избавиться?

Ответы [ 2 ]

16 голосов
/ 29 октября 2011

Вы объявили свой метод как метод класса, и вы пытаетесь использовать объект Class в качестве делегата.Но вы не можете добавлять протоколы к объектам Class.

Вам нужно изменить playAudioFromFileName:... на метод экземпляра и создать экземпляр Utility для использования в качестве делегата.Возможно, вы хотите, чтобы один экземпляр Utility был доступен всем абонентам.Это паттерн Синглтона, и он довольно распространен в Какао.Вы делаете что-то вроде этого:

Utility.h

@interface Utility : NSObject <AVAudioPlayerDelegate>
+ (Utility *)sharedUtility;
@end

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

Использование

[[Utility sharedUtility] playAudioFromFileName:@"quack" ofType:"mp3" withPlayerFinishCallback:@selector(doneQuacking:) onObject:duck];
6 голосов
/ 19 августа 2013

Если вам не нужен экземпляр класса, просто получите предупреждение:

audioPlayer.delegate = (id<AVAudioPlayerDelegate>)self;

С другой стороны, обратите внимание, что если вам нужен делегат, это означает, чтоиметь экземпляр класса в качестве хорошей практики кодирования вместо статического класса.Это может быть легко синглтон :

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