7

私は次のようなクラスを持っています:

@interface Properties : NSObject {
@private
    NSNumber* prop1;
    NSNumberBool* prop2;
    //etc

ここで、NSNumberBoolはtypedefです。

// in MyApp_Prefix.pch
typedef NSNumber NSNumberBool;

prop1およびprop2プロパティを作成するために必要なすべての@propertyおよび@synthesize宣言があります。

[myProperties valueForKey:@ "prop2"]でprop2にアクセスしようとするまで、すべてがコンパイルされ、正常に機能しました。これにより、「クラスはKey-Valueに準拠していません」というエラーが発生します。ただし、多くの同様の呼び出しは正常に機能します。

myProperties.prop2; //works
[myProperties prop2]; //works
[myProperties valueForKey:@"prop1"]; //works
[myProperties valueForKey:@"prop2"] // throws NSUnknownKeyException ??

ここで何が起こっているのですか、どうすれば修正できますか?

ありがとう、

4

4 に答える 4

5

例をコンパイルしてクラスダンプを発行すると、typedefが次のようになります。

struct NSNumber {
    Class _field1;
};

@interface Properties : NSObject
{
    NSNumber *prop1;
    struct NSNumber *prop2;
}

typedefをこれに変更すると、うまくいくように見えますが、正確には希望どおりではない可能性があります。

#define NSNumberBool NSNumber
于 2009-10-16T07:32:46.197 に答える
5

これは、typedefがencodeメソッドと相互作用する方法の問題だと思います。

typedefは純粋なCキーワードのままであり、実際にはObjective-Cの「型」でのみ機能すると思います。これは、通常、構造体として実装されているためです。

その結果、NSNumberをNSNumberBoolにtypedefすると、メソッド呼び出し(およびドット構文プロパティ)では正常に機能しますが、(私の理論が正しいと仮定して)ブレークはエンコードを中断し、NSNumberBoolとNSNumberが同じタイプであることを認識できません。

よく知っている人の言うことを知りたいです。

于 2009-10-16T07:36:09.877 に答える
2

@compatibility_aliasこれはかなり古い投稿ですが、Objective-C 2.0ディレクティブによってうまく解決される、この問題の解決策を探しているときに私はそれに到達しました。これにより、次のように書くことができます。

@compatibility_alias NSNumberBool NSNumber;

のエイリアスを作成しNSNumberます。KVOはそれと完全に連携します。

現在受け入れられている答えに比べて、これにはタイプセーフであるという大きな利点があります。

于 2016-07-25T10:26:44.403 に答える
1

nallの答えと同様に、私もclass-dumpを試しました。醜い回避策であれば、私は興味深いものを見つけました。次のコード:

typedef NSNumber* NSNumberBoolPtr;

@interface Test : NSObject {
    NSNumber *real;
    NSNumberBoolPtr poser;
}

クラスダンプ先:

@interface Test : NSObject
{
    NSNumber *real;
    NSNumber *poser;
}

@end

繰り返しになりますが、正確には必要なものではありませんが、NSNumbersとNSNumberBoolsが混在していないかどうかのコンパイラ時チェックが行われます(これが、最初にtypedefの理由であると思います)。

于 2009-11-16T19:50:42.907 に答える