1

我创建了一个包含三个核心音频类型属性的类:

@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 方法的“字节”版本似乎是正确的方法。

关于我可能出错的地方有什么想法吗?

4

1 回答 1

0

如果您看一下,decodeBytesForKey:returnedLength:您会看到这returnedLength是 aNSUInteger*并且您正在传递一个整数。除了方法返回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前缀命名属性并不是惯例。

于 2013-06-22T01:09:43.603 回答