1

在了解类别之前,我在生成的 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有关?但无论如何,我能做什么?您不能在类别中声明实例变量,这样就不行了。

4

2 回答 2

0

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

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

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

在实施中:

@synthesize audioPlayer = _audioPlayer;

最后一部分隐式地_audioPlayer为您的属性创建了一个 ivar。您可以直接访问它,但我建议仍然扔 setter self.audioPlayer =

于 2012-07-12T17:48:37.593 回答
0

我在解释我在 Apple 开发者论坛上学到的东西:

由于 ARC,局部变量在离开作用域时将被释放。所以在方法中声明的 AVAudioPlayer 将在它有机会播放之前消失。虽然在某些情况下可以添加 IVAR,但这里不是。原因是您无法将 IVAR 添加到类别中。详细地说,上面的 NSManagedObject 子类是由 XCode 生成的——如果我向实体添加了 IVAR,当我更改实体并重新生成时,它会被 XCode 覆盖。

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

于 2012-07-12T18:48:18.030 回答