您的示例留下了许多变量,需要任何潜在的帮助者质疑。例如:如果这个 unarchiver 有什么奇怪的地方怎么办?内存管理是否正确?
我能够重现您所看到的崩溃,并且可以确认它仅在启用 -O3 时发生,而不是在选择例如 None 进行优化时发生。这是崩溃代码的减少,它消除了外部变量,例如编码器的内存管理等。请注意,下面的代码有意保留所有对象,以消除崩溃与意外过度释放或侧面有关的可能性-正如安迪在另一个答案中所建议的那样,使用 ARC 的效果:
typedef struct
{
NSInteger x;
NSInteger y;
}
BBPointI32;
- (void) testDecoding
{
NSString* myKey = @"Testing";
// First get an coder with bytes in it
NSMutableData* myData = [[NSMutableData data] retain];
NSKeyedArchiver* myCoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:myData];
BBPointI32 encodedStruct = {1234, 5678};
[myCoder encodeBytes:(const uint8_t *)&encodedStruct length:sizeof(encodedStruct) forKey:myKey];
[myCoder finishEncoding];
// Now decode it
BBPointI32 decodedStruct;
NSUInteger decodedLength = 0;
NSKeyedUnarchiver* myDecoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:myData];
uint8_t* data = (uint8_t*)[myDecoder decodeBytesForKey:myKey returnedLength:&decodedLength];
decodedStruct = *(BBPointI32*)data;
NSLog(@"Got decoded struct with x = %ld, y = %ld, length = %lu", decodedStruct.x, decodedStruct.y, decodedLength);
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(@"Testing decoding");
[self testDecoding];
}
我认为这对问题提供了更简洁的描述,任何想要帮助的人都可以将其用作深入研究的基础。到目前为止,我的预感是这是 LLVM 3.0 中的一个优化错误,但也许其他人会有更好的理论到底是怎么回事。
您在问题中没有提到但我在设备崩溃中注意到的一点是,失败伴随着提到 EXC_ARM_DA_ALIGN 错误作为错误访问异常的原因。我在 Google 上搜索了一篇博客文章,该文章似乎暗示了相同的症状,并且可能导致您在此处看到的崩溃:
http://www.galloway.me.uk/2010/10/arm-hacking-exc_arm_da_align-exception/
事实上,通过改变上面的行
decodedStruct = *(BBPointI32*)data;
到
memcpy(&decodedStruct, data, sizeof(decodedStruct));
崩溃行为似乎得到缓解,代码表现如预期。