AVAudioPlayer没有IVAR就玩了

时间:2012-07-12 17:42:02

标签: ios avfoundation

在我学习类别之前,我在生成的NSManagedObject子类中为我的实体声明了一个方法:

// 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有关?但无论如何,我该怎么办?您不能在类别中声明实例变量,以便不这样做。

2 个答案:

答案 0 :(得分:0)

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

在实现中的头文件或接口声明中:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

在实施中:

@synthesize audioPlayer = _audioPlayer;

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

答案 1 :(得分:0)

我在Apple开发者论坛上解释了我learned

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

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