在我学习类别之前,我在生成的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有关?但无论如何,我该怎么办?您不能在类别中声明实例变量,以便不这样做。
答案 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 *作为类别方法的参数,并在调用该方法时将其传递。