给出以下压缩结构:
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"
字符串。 (我实际想要实现的是递归打印对象内容)。
答案 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不是也不会是id
。 valueForKey:
返回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
。我认为这只是在你的例子中。