1

いくつかのフラグを格納するために使用される NSNumber を持つ単純なオブジェクトがあります。私は実際に行う便利なゲッターメソッドを持っています:

[self.flags integerValue] & SomeConstantFlag

プロパティの@property (readonly, nonatomic, assign) BOOL someConstantFlag

これは、次のような基になるブール値にアクセスするときに正常に機能します

model.someConstantFlag

しかし、私がしようとすると

id value = [model valueForKey:@"someConstantFlag"];

次に、値 2、4 などの NSNumber などの不適切なブール表現を返します。プロパティの宣言が BOOL の場合、なぜこれが発生するのですか? この問題を克服する「きれいな」方法はありますか?

一方、ラッピングは問題なく機能します。

BOOL someBool = 42;
NSNumber* numberVal = @(someBool);
//The underlying is an __NSCFBoolean with the proper 0/1 val!
4

3 に答える 3

0

以下の問題を考えたほうがいいと思います。まず、integerValue は NSInteger を返します。これは、64 ビット アーキテクチャをサポートしている場合、int_32 ではなく int_64 を返すことを意味します。

    [self.flags integerValue] & SomeConstantFlag

flags が 00010 で somConstantFlags が 00001 の場合、これは次のようになります。0 に等しい 00000 の値を取得するか、00011 と 00110 の場合は 2 に等しい 00010 を取得するため、これらの & はおそらく予期しないことを行います。そのため、valueForKey を呼び出すと、フラグに応じて 2 または 4 またはその他の値が返されます :) Objective-C ではさらに、0 以外のすべてが YES です。

ビットロジックを再考してみてください:)。次の例を参照してください

    enum 
    {
    kWhite   = 0,
    kBlue    = 1 << 0,
    kRed     = 1 << 1,
    kYellow  = 1 << 2,
    kBrown   = 1 << 3,
    };
    typedef char ColorType;

そしてあなたのセッターで以下をチェックしてください

ColorType pinkColor = kWhite | kRed;
if (pinkColor & (kWhite | kBlue | kRed | kYellow)) {
// any of the flags has been set
}

フラグ kWhite、kBlue、kRed、kYellow が設定されています。

ただし、kBrown は設定されていません。

于 2014-04-29T09:13:57.950 に答える
0
NSNumber *value = @([model objectForKey:@"someConstantFlag"]);

BOOL boolVal = [value boolValue];
于 2014-04-29T09:02:47.330 に答える
0

valueForKeyプロパティがスカラー型であっても、常に Objective-C オブジェクトを返します。

ドキュメントから(強調鉱山):

のデフォルトの実装は、非オブジェクト データ型 (スカラーと構造体の両方) の自動オブジェクト ラッピングvalueForKey:setValue:forKey: サポートします。

valueForKey:指定されたキーの値を提供するために使用される特定のアクセサ メソッドまたはインスタンス変数が決定されると、戻り値の型またはデータ型が調べられます。返される値がオブジェクトでない場合、その値に対してorNSNumberオブジェクトNSValueが作成さ れ、その場所に返されます。

メソッドの戻り値はBOOLであり、次のように定義されています。

typedef signed char BOOL;

OS X および 32 ビット iOS プラットフォームで。したがって、valueForKey返されるのは、NSNumber の結果を含む

signed char val = [self.flags integerValue] & SomeConstantFlag;

範囲は -128 .. 127 です。

YESまたは(別名 1 または 0)のみを確実に取得するにはNO、カスタム ゲッターを次のように記述します。

-(BOOL)someConstantFlag
{
    return ([self.flags integerValue] & SomeConstantFlag) != 0;
}

備考: 64 ビット iOS プラットフォームでは (64 ビット OS X ではなく)、BOOLは C99 として定義されてい_Boolます。これは「適切な」ブール型であり、値 0 または 1 のみを取ることができます。

于 2014-04-29T08:59:42.047 に答える