分配给“id”的不兼容指针类型来自“班级”

发布于 2024-12-13 02:58:56 字数 942 浏览 2 评论 0原文

我有一个实现 AVAudioPlayerDelegate 协议的“Utility”类。

这是我的 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 应用程序运行良好,但是在迁移到 iOS 5 和 Xcode 4.2 后,编译器开始抛出此警告,位于 audioPlayer.delegate = self; 行:

Incompatible pointer types assigning to id <AVAudioPlayerDelegate> from 'Class'

我怎样才能摆脱它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷夜 2024-12-20 02:58:56

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

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

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];

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:

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

Usage

[[Utility sharedUtility] playAudioFromFileName:@"quack" ofType:"mp3" withPlayerFinishCallback:@selector(doneQuacking:) onObject:duck];
绻影浮沉 2024-12-20 02:58:56

当您不需要类的实例时,只需手动消除警告:

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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文