0

我的目标是以这种方式将 audioPlayer 实例的引用存储在核心数据中,以便稍后我可以在该条目上使用属性。像这样:

-(void)didTapButton
{
    if (!self.sound.audioPlayer.playing)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"playSound" object:self.sound];
        self.soundProgress.hidden = NO;
    } else {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"stopSound" object:self.sound];
        self.soundProgress.hidden = YES;
    }
}

我的 MOS 看起来像这样

@interface MCSound : NSManagedObject

@property (nonatomic, retain) AVAudioPlayer *audioPlayer;
@property (nonatomic, retain) NSString * category;
@property (nonatomic, retain) NSString * duration;
@property (nonatomic, retain) NSString * fileURL;
@property (nonatomic, retain) NSString * id;
@property (nonatomic, retain) NSNumber * isLooping;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * theme;
@property (nonatomic, retain) MCTheme *ofTheme;

@end

到目前为止有效。但是,如果我再次生成 MOS,则 AVAudioPlayer 类将被 id 替换。有没有办法我可以用类别做到这一点?我是否必须在类别之后使用我的声音实例的类别?

编辑

我需要在应用程序运行时引用 AVAudioPlayer,因为我经常切换视图,并且 AVAudioPlayer 被初始化为一个 gridView。结构是:

gridView -> detailView -> soundButton

按钮向设置了 AVAudioPlayer 的 gridView 发送通知。当我回到 detailView 时,我必须显示声音是否仍在播放,并且正在播放的时间必须显示在进度条上。我使用 NSMutableDisctionary 进行了所有操作,但现在切换到核心数据模型,因为我必须使用默认声音集预填充数据库。

因此,我认为这是在录音中引用 AVAudioPlayer 的最佳方式。因为当我回到detailView时需要audioPlayer的引用。我必须知道它是否还在播放和播放时间。

你会怎么解决?

4

1 回答 1

1

不应将 AVAudioPlayer 添加到 core-data 中的持久存储中,因为它不符合 NSCoding 协议。

我要做的是从您的模型中删除 AVAudioPlayer,但将其保留在您的 NSManagedObject 中。然后在实现中将音频播放器的@dynamic 切换为@synthesized。(也添加一行以在 dealloc 上释放音频播放器)。

然后做这样的事情

-(AVAudioPlayer*)audioPlayer {
if (self.audioPlayer) return audioPlayer;
else {
NSError * error = nil;
AVAudioPlayer * lAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:self.fileURL error:&error];

if (!error) {
self.audioPlayer = lAudioPlayer;
[lAudioPlayer release];
} else {
[lAudioPlayer release];
NSLog(@"%@",error);
}

}

}

我还建议使用与 isLooping 和 duration 类似的东西,并让它们直接从 audioPlayer 中取出,而不是将它们存储在持久存储中,除非你需要它们持久保存。

编辑

听起来您的问题是您在对象中引用 avaudioplayer(为了持久性)然后保存上下文,然后当您返回时从持久存储重新请求对象,这将不起作用,因为您的持久存储无法处理音频播放器。有多种方法可以解决这个问题。

第一个是将所有 avaudioplayers 存储在 nsmutabledictionary 中(我会将其设为静态或单例)。这个 nsmutabledictionary 将由一个唯一标识符作为关键字。您可以创建一个唯一标识符并将其存储在您的持久存储中(在您的对象上有一个新属性),或者只使用声音对象的 objectid(我相信)。那时,按照我之前所说的在您的托管对象类中创建 audioPlayer,而不是在那里创建它,只需使用已创建的唯一标识符从 nsmutabledictionary 中取回它,如果没有,则意味着您需要创建一个新的音频播放器并将其添加到 nsmutabledictionary。

我希望我能理解你的问题,我认为这是最简单的解决方案,也是最优雅的。另一个非常简单的方法是您将所有正在播放的声音管理对象保存在内存中,这样您就不需要从持久存储中重新请求它们,因此您的音频播放器仍然可以访问。

确实有一千种方法可以做到这一点,我只是给你我会使用的 2 个,当你完成它们时,不要忘记释放你的音频播放器并将它们从可变字典中删除。

于 2012-11-08T01:21:35.383 回答