valueForKey:在打包的struct上?

时间:2013-02-08 15:44:31

标签: ios objective-c struct

给出以下压缩结构:

typedef struct __attribute__((packed)) {
    BOOL flag;
    int x;
} Foo;

以下课程:

@interface Obj : NSObject
@property (nonatomic) Foo foo;
@end

@implementation Obj
@end

尝试在具有打包结构类型的属性上调用valueForKey:

Obj *obj = [Obj new];
id boo = [obj valueForKey:@"foo"];

导致valueForKey:内部崩溃(实际上它不会在valueForKey:内崩溃,而是在随机位置,具体取决于月亮大小,我猜这是内存损坏。)

如果删除__attribute__((packed)),则可以正常使用。 有没有可能在没有崩溃的情况下获取struct的数据?这是Apple的错误吗?

PS。我确实需要在运行时执行它,即我不能直接调用.foo,我在运行时只有@"foo"字符串。 (我实际想要实现的是递归打印对象内容)。

2 个答案:

答案 0 :(得分:0)

避免KVO用于您的使用案例,并坚持使用方便的花花公子<objc/runtime.h>标题。您可以使用这种内省重新实现KVO的基本部分。结构打包主要用于确保编译器未正确对齐内部字段,因此CPU在执行期间无需在硬件级别处理它。在这个时代,最好让编译器为你处理一些事情。

如果您真的更喜欢这种结构包装(正如您所说,在网络传输方案中),我需要更多信息来确定问题所在。也许尝试将@property (nonatomic) Foo foo;更改为@property (nonatomic) NSValue *foo;,然后将其装箱并自行拆箱?这样,异常/错误将出现在应用程序的域中。

答案 1 :(得分:0)

我不知道这是否可以使用属性,但如果是,我认为你没有使用正确的语法。

您是否尝试过更改

id boo = [obj valueForKey:@"foo"]; 

阅读

Foo boo = obj.foo;

Foo不是也不会是idvalueForKey:返回id,运行时可能正在试图将struct Foo压缩到NSValue

如果由于某种原因需要使用valueForKey:,则您的访问需要看起来像。

Foo myFoo = FooFactory();
Object *myObj = [Object new];
[myObj setValue:@( myFoo ) forKey:@"foo"];

Foo myFooOut;
[[myObj valueForKey:@"foo"] getValue:&myFooOut];
//I bet `getValue:` is where things are barfing.

在这种情况下,如果NSValue的机器确实无法处理打包的结构,你只需要用老式的方式编写访问器:-<key>和-set:`。

PS:永远不要将类命名为“对象”,Object继承的某些SDK中实际上存在NSObject。我认为这只是在你的例子中。