2012-07-12 54 views
1

之前,我学到了类,我有一个宣布为我在生成的NSManagedObject子类实体的方法:AVAudioPlayer不打无伊娃

// UserRecording.h 

#import <Foundation/Foundation.h> 
#import <CoreData/CoreData.h> 
#import <AVFoundation/AVFoundation.h> 

@interface UserRecording : NSManagedObject { 
    AVAudioPlayer *audioPlayer; 
} 

@property (nonatomic, retain) NSDate * dateCreated; 
@property (nonatomic, retain) NSData * audioData; 
@property (nonatomic, retain) NSString * name; 

-(void) URplay; 

@end 

和这里的实现:

// UserRecording.m 


#import "UserRecording.h" 

@implementation UserRecording 

@dynamic dateCreated; 
@dynamic audioData; 
@dynamic name; 

-(void) URplay { 
    NSError *error; 
    audioPlayer = [[AVAudioPlayer alloc] initWithData:self.audioData error:&error]; 
    [audioPlayer play]; 
} 

@end 

当我了解了类别(通过斯坦福iTunes U视频),我将代码移到了一个类别中。但声音停止播放。唯一的区别是没有声明的实例变量(IVAR)。事实上,我在旧代码中测试过它。上面的代码播放音频,但是这个代码犯规(在模拟器):

// UserRecording.h 

#import <Foundation/Foundation.h> 
#import <CoreData/CoreData.h> 

@interface UserRecording : NSManagedObject 

@property (nonatomic, retain) NSDate * dateCreated; 
@property (nonatomic, retain) NSData * audioData; 
@property (nonatomic, retain) NSString * name; 

-(void) URplay; 

@end 

和实现:

// UserRecording.m 

#import "UserRecording.h" 
#import <AVFoundation/AVFoundation.h> 

@implementation UserRecording 

@dynamic dateCreated; 
@dynamic audioData; 
@dynamic name; 

-(void) URplay { 
    NSError *error; 
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:self.audioData error:&error]; 
    [audioPlayer play]; 
} 

@end 

也许有事情做与ARC?但无论如何,我能做什么?你不能在一个类别中声明一个实例变量,所以不能这样做。

回答

0

我转述了我learned在苹果开发者论坛:

由于ARC,局部变量将被释放,当他们离开的范围。所以在该方法中声明的AVAudioPlayer在它有机会玩之前将消失。虽然在某些情况下添加IVAR是可能的,但事实并非如此。原因是您不能将IVAR添加到类别中。详细来说,上面的NSManagedObject子类是由XCode生成的 - 如果我向该实体添加了一个IVAR,当我更改实体&重新生成时,它将被XCode覆盖。

因此,解决方案是重新考虑我持久的AVAudioPlayer应该去的地方。我可能会添加一个持久的AVAudioPlayer *作为类的方法的参数,并在方法被调用时传递它。

0

它与ARC有关,意思是说你的AVAudioPlayer在实例化后立即被取消分配,因为在你离开范围时,局部变量被释放,尝试为它声明属性,你不需要一个实例变量本身:

在实施头文件或接口声明:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 

在实现:

@synthesize audioPlayer = _audioPlayer; 

这最后一部分隐含地为您的财产创建了一个ivar _audioPlayer。你可以直接访问它,但我建议仍然会抛出setter self.audioPlayer =

+0

谢谢,但正如我所提到的目标是把它放在一个类别。所以我不能使用财产&综合(没有IVARs)。而且我无法编辑实体文件,因为它会在某个时候重新生成,我会失去我的方法。原来我需要重新考虑这个设计,因为我需要持久的AVAudioPlayer(s)。 – 2012-07-12 18:42:43

+1

对不起,你需要的只是AVAudioPlayer的引用,例如,我看到你的对象只是拥有属性和音频播放器。如何简单地从对象中移除音频播放器,在控制器中设置它,然后使用对象中的音频数据播放它。听起来更合理。 – 8vius 2012-07-12 18:52:08

+0

这几乎是我所做的(见下文)。我只是测试它,它的工作原理。事实上,我摆脱了这个范畴。这是错误的设计 - 你不能“播放”录音,你只能“播放”AVAudioPlayer。 – 2012-07-12 19:32:15