取消引用NSCoder的decodeBytesForKey返回的指针时,iOS设备崩溃

Mat*_*omi 8 iphone xcode arm llvm nscoder

在使用Apple LLVM编译器3.0并使用-O3编译时,我发现了一个与NSCoder不同的错误.它只会在设备上崩溃.我测试了运行iOS 5的iPhone 4,运行iOS 5的iPad 2和运行iOS 4的iPad 1.所有都崩溃了.这是相关的代码部分:

-(id)initWithCoder:(NSCoder*)decoder
{
    if (![super init])
    {
        return nil;
    }

    NSUInteger length = 0;

    uint8_t* data = (uint8_t*)[decoder decodeBytesForKey:BBKey returnedLength:&length];

    m_value = *(BBPointI32*)data;

    return self;
}
Run Code Online (Sandbox Code Playgroud)

这就是BBPointI32:

typedef struct
{
    NSInteger x;
    NSInteger y;
}
BBPointI32;
Run Code Online (Sandbox Code Playgroud)

取消引用EXC_BAD_ACCESS时会发生这种情况data.这不是空指针问题.如果我附加GDB,我可以看到长度是8,sizeof(BBPointI)也是8,数据是正确的.

如果我查看反汇编,崩溃就发生在:

ldrd    r2, r3, [r0]
Run Code Online (Sandbox Code Playgroud)

看起来不错.r0包含0xb546e,这是地址data.当我检查那个内存时,我可以看到它包含我期望的数据.对于任何感兴趣的人,r2包含72(不确定是什么),r3包含8(最可能是值length).

任何人都可以对这个问题有所了解吗?

小智 10

ldrd需要地址为8字节对齐.*(BBPointI32*)数据习惯用法不安全,因为数据不是8字节对齐的.使用memcpy将字节输入结构中.