我有一个简单的对象,它有一个NSNumber,用于存储一些标志。 我有一个方便的getter方法实际上做了:
[self.flags integerValue] & SomeConstantFlag
获取属性@property (readonly, nonatomic, assign) BOOL someConstantFlag
这在访问基础bool值(如
)时工作正常model.someConstantFlag
但是当我尝试
时id value = [model valueForKey:@"someConstantFlag"];
然后它返回一个错误的布尔表示,例如NSNumber值为2,4等 当财产声明为BOOL时,为什么会发生这种情况?有没有"漂亮"克服这个问题的方法?
另一方面,包装工作正常:
BOOL someBool = 42;
NSNumber* numberVal = @(someBool);
//The underlying is an __NSCFBoolean with the proper 0/1 val!
答案 0 :(得分:0)
valueForKey
总是返回一个Objective-C对象,即使该属性具有标量类型。
来自documentation(强调我的):
valueForKey:
和setValue:forKey:
的默认实施 为非对象数据的自动对象包装提供支持 类型,标量和结构。
valueForKey:
确定了特定的访问方法或 实例变量,用于提供指定的值 key,它检查返回类型或数据类型。如果值是 返回的不是对象,创建了NSNumber
或NSValue
对象 为该值而返回。
您的方法的返回值为BOOL
,定义为
typedef signed char BOOL;
在OS X和32位iOS平台上。那么valueForKey
返回的是NSNumber
包含
signed char val = [self.flags integerValue] & SomeConstantFlag;
,可以在-128 .. 127范围内。
要确保您只获得YES
或NO
(也称为1或0),请将自定义getter编写为:
-(BOOL)someConstantFlag
{
return ([self.flags integerValue] & SomeConstantFlag) != 0;
}
备注:在64位iOS平台上(但不在64位OS X上),BOOL
被定义为C99 _Bool
,这是一个“适当的“布尔类型,只能取值0或1。
答案 1 :(得分:0)
NSNumber *value = @([model objectForKey:@"someConstantFlag"]);
BOOL boolVal = [value boolValue];
答案 2 :(得分:0)
我认为你应该考虑以下问题。首先,integerValue返回NSInteger,这意味着如果你支持64Bit架构,它将返回int_64而不是int_32,这里的代码更多
[self.flags integerValue] & SomeConstantFlag
如果flags为00010且somConstantFlags为00001&,则执行以下操作:那些会做你可能没想到的东西,因为你会得到00000的值等于0或者如果它们是00011和00110你会得到00010等于2.所以这就是为什么当你调用valueForKey时你会得到2或4或者其他什么否则取决于你的标志:) 更重要的是目标-C一切都不同于0。是的。
尝试重新考虑你的位逻辑:)。请参阅以下示例
enum
{
kWhite = 0,
kBlue = 1 << 0,
kRed = 1 << 1,
kYellow = 1 << 2,
kBrown = 1 << 3,
};
typedef char ColorType;
并在你的setter中查看以下内容
ColorType pinkColor = kWhite | kRed;
if (pinkColor & (kWhite | kBlue | kRed | kYellow)) {
// any of the flags has been set
}
已经设置了标志kWhite,kBlue,kRed和kYellow。
但是,还没有设置kBrown。