I have a "Utility" class that implements the AVAudioPlayerDelegate protocol.
This is my Utility.h
@interface Utility : NSObject <AVAudioPlayerDelegate>
{
}
And this is its counterpart 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
...
}
My iOS application works well, however after migrating to iOS 5 and Xcode 4.2 the compiler started throwing this warning, located at the audioPlayer.delegate = self;
line:
Incompatible pointer types assigning to id <AVAudioPlayerDelegate> from 'Class'
How can I get rid of it?
You've declared your method as a class method, and you're trying to use the Class object as the delegate. But you can't add protocols to Class objects.
You need to change playAudioFromFileName:...
to an instance method and create an instance of Utility
to use as the delegate. Maybe you want to have a single instance of Utility
shared by all callers. This is the Singleton pattern, and it's pretty common in Cocoa. You do something like this:
@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];
When you don't need an instance of a Class, just manually get ride of the warning:
audioPlayer.delegate = (id<AVAudioPlayerDelegate>)self;
On the other hand, please note that if you need a Delegate, it means you should have an instance of a Class as a good coding practice instead of a static Class. It can be made a singleton easily:
static id _sharedInstance = nil;
+(instancetype)sharedInstance
{
static dispatch_once_t p;
dispatch_once(&p, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With