我有一个简单的对象,它有一个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!I have a simple object which has one NSNumber which is used to store some flags. I have a conienience getter method which in fact does:
[self.flags integerValue] & SomeConstantFlagfor a property@property (readonly, nonatomic, assign) BOOL someConstantFlag
and this works fine when accesing the underlying bool value like
model.someConstantFlagbut when I try to
id value = [model valueForKey:@"someConstantFlag"];Then it returns a bad boolean representation e.g. NSNumber with value 2, 4 etc. Why is this happening when the declaration of the property is BOOL? Is there a "Pretty" way to overcome this issue?
Wrapping on the other hand works ok:
BOOL someBool = 42; NSNumber* numberVal = @(someBool); //The underlying is an __NSCFBoolean with the proper 0/1 val!最满意答案
valueForKey始终返回Objective-C对象,即使该属性具有标量类型。
从文档 (强调我的):
valueForKey:和setValue:forKey:的默认实现setValue:forKey:支持非对象数据类型(标量和结构)的自动对象包装。
一旦valueForKey:确定了用于为指定键提供值的特定访问器方法或实例变量,它将检查返回类型或数据类型。 如果要返回的值不是对象,则为该值创建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。
valueForKey always returns an Objective-C object, even if the property has scalar type.
From the documentation (emphasis mine):
The default implementations of valueForKey: and setValue:forKey: provide support for automatic object wrapping of the non-object data types, both scalars and structs.
Once valueForKey: has determined the specific accessor method or instance variable that is used to supply the value for the specified key, it examines the return type or the data type. If the value to be returned is not an object, an NSNumber or NSValue object is created for that value and returned in its place.
The return value of your method is BOOL, which is defined as
typedef signed char BOOL;on OS X and on the 32-bit iOS platform. So what valueForKey returns is a NSNumber containing the result of
signed char val = [self.flags integerValue] & SomeConstantFlag;and that can be in the range -128 .. 127.
To ensure that you get only YES or NO (aka 1 or 0) write your custom getter as:
-(BOOL)someConstantFlag { return ([self.flags integerValue] & SomeConstantFlag) != 0; }Remark: On the 64-bit iOS platform (but not on 64-bit OS X), BOOL is defined as the C99 _Bool, which is a "proper" boolean type and can take only the value 0 or 1.
更多推荐
发布评论