4

次のパックされた構造体が与えられます:

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))問題なく動作します。クラッシュせずに構造体のデータを取得する可能性はありますか?それはAppleのバグですか?

PS。実行時に行う必要があります。つまり、.foo直接呼び出すことはできません@"foo"。実行時に文字列しかありません。(私が実際に達成しようとしているのは、オブジェクトの内容を再帰的に印刷することです)。

4

2 に答える 2

0

ユース ケースでは KVO を避け、便利なダンディ<objc/runtime.h>ヘッダーを使用してください。この種のイントロスペクションを使用して、KVO の基本的な部分を再実装できます。構造体パッキングは主に、コンパイラが内部フィールドを適切に整列しないようにするために使用されるため、CPU は実行中にハードウェア レベルでそれを処理する必要がありません。この時代では、コンパイラーに処理を任せたほうがよいでしょう。

あなたが本当にこの構造体のパッキングを好むなら (あなたが言ったように、ネットワーク伝送のシナリオで)、問題がどこにあるのかを判断するためにさらに情報が必要です. おそらく、自分で変更@property (nonatomic) Foo foo;@property (nonatomic) NSValue *foo;てから箱に入れ、箱から出してみてください。このようにして、例外/エラーはアプリケーションのドメインになります。

于 2013-02-08T15:55:09.077 に答える
0

プロパティでこれが可能かどうかはわかりませんが、可能であれば正しい構文を使用しているとは思いません。

変えてみましたか

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

読む

Foo boo = obj.foo;

?

Foo はid. valueForKey:は id を返し、ランタイムstruct FooNSValue.

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継承元があります。それはあなたの例にあると思います。

于 2013-02-08T17:15:02.543 に答える