我创建了一个包含三个Core Audio类型属性的类:
@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,所以我完全没有信心我正在远程正确地做这件事。
这三种Core Audio数据类型是结构,因此使用encode / init NSCoder方法的“字节”版本似乎是正确的方法。
关于我可能出错的任何想法?
如果你看看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
前缀来命名属性不是一种约定。