2013-06-21 86 views
0

我已經創建了一個包含三個屬性,核心音頻類型的類:使用NSCoding與核心音頻類型

@interface AudioFilePlayer : NSObject <NSCoding> 

@property (assign) AudioUnit      mAudioUnit; 
@property (assign) AUNode       mNode; 
@property (assign) AudioStreamBasicDescription  mStreamFormat; 

@end 

我的應用程序保存類型AudioFilePlayer的對象的數組,我想封存和解除封存他們使用NSCoding。我已經寫了encodeWithCoder:和的initWithCoder:方法如下:

- (void)encodeWithCoder:(NSCoder *)aCoder 
{   
    [aCoder encodeBytes:(uint8_t*)&_mAudioUnit length:sizeof(AudioUnit) forKey:@"mAudioUnit"]; 
    [aCoder encodeBytes:(uint8_t*)&_mNode length:sizeof(AUNode) forKey:@"mNode"]; 
    [aCoder encodeBytes:(uint8_t*)&_mStreamFormat length:sizeof(AudioStreamBasicDescription) forKey:@"mStreamFormat"]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder 
{   
    self = [super init]; 
    if (self) { 
     [self setMAudioUnit:(AudioUnit)[aDecoder decodeBytesForKey:@"mAudioUnit" returnedLength:sizeof(AudioUnit)]]; 

     [self setMNode:(AUNode)[aDecoder decodeBytesForKey:@"mNode" returnedLength:sizeof(AUNode)]]; 
     [self setMStreamFormat:*(AudioStreamBasicDescription*)[aDecoder decodeBytesForKey:@"mStreamFormat" returnedLength:sizeof(AudioStreamBasicDescription)]]; 
    } 

    return self; 
} 

我能夠編碼/歸檔成功(即寫入一個文件並沒有返回錯誤......我不知道它的實際工作),但是當我啓動應用程序,並嘗試解碼/解除存檔對象,應用程序崩潰與:在這條線

Thread 1: EXC_BAD_ACCESS (code=2,address=0x4) 

在我initWithCoder method

[self setMAudioUnit:(AudioUnit)[aDecoder decodeBytesForKey:@"mAudioUnit" returnedLength:sizeof(AudioUnit)]]; 

這是我的冷杉使用NSCoding的時間,所以我沒有充分的信心,我做這個甚至遠程正確。

這三個核心音頻數據類型是結構體,因此使用編碼/初始NSCoder方法的「字節」版本似乎是正確的方法。

任何關於我可能會出錯的想法?

在此先感謝!

+0

要在coreaudio郵件列表上回應關於此問題的內容,AudioUnits和AUNodes是對象,並且這不會按預期工作。 – sbooth

+0

對。在我的情況下,並不需要存檔音頻單元或AUNode對象。相反,可以在運行時重新創建這些對象,以及隨附的AUGraph。 – Nick

回答

0

如果你看看decodeBytesForKey:returnedLength:你會發現returnedLength是一個NSUInteger*,你傳遞一個整數。除了該方法返回const uint8_t*,所以你需要取消引用它來取回你的數據。

而不是

[self setMAudioUnit:(AudioUnit)[aDecoder decodeBytesForKey:@"mAudioUnit" returnedLength:sizeof(AudioUnit)]]; 

應該

NSUInteger szAudioUnit; 
const uint8_t* audioUnitBytes = [aDecoder decodeBytesForKey:@"mAudioUnit" returnedLength:&szAudioUnit]; 
AudioUnit* pAudioUnit = (AudioUnit*)audioUnitBytes; 
self.mAudioUnit = *pAudioUnit; 

其實我不知道你怎麼代碼編譯,甚至!

在附註中,也許只是我的看法,Objective-C中的慣例不是用m前綴命名屬性。

+0

感謝這個Khanh,它工作。我從那以後就知道,嘗試將音頻單元和AUNodes寫入磁盤並不是一個好主意,至少在沒有仔細考慮填充,字節順序和對齊的情況下不是一個好主意。 – Nick