将NSCoding与核心音频类型配合使用

问题描述 投票:1回答:1

我创建了一个包含三个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方法的“字节”版本似乎是正确的方法。

关于我可能出错的任何想法?

ios core-audio nscoding
1个回答
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前缀来命名属性不是一种约定。

© www.soinside.com 2019 - 2024. All rights reserved.