あなたの例では、潜在的なヘルパーが疑問視する多くの変数が残されています。例: この 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));
クラッシュ動作は軽減されたようで、コードは期待どおりに動作します。