2012-07-12 34 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