BOOL 属性 KVC:这种行为是错误吗?
BOOL property KVC: is this behavior a bug?
似乎 valueForKey:
具有 BOOL
@property
键的名称 returns 不同的类型(因此,导致不同的 JSON 序列化) 在 64 位和 32 位 iOS 系统上:
在 32 位(iPhone 4s 模拟器上):
8 * sizeof(void*) = 32
boolProperty attributes: Tc,N,V_boolProperty
obj.boolProperty = YES
[obj valueForKey:@"boolProperty"]: 1
[[obj valueForKey:@"boolProperty"] class]: __NSCFNumber
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":1}
obj.boolProperty = NO
[obj valueForKey:@"boolProperty"]: 0
[[obj valueForKey:@"boolProperty"] class]: __NSCFNumber
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":0}
64 位(iPhone 6 模拟器):
8 * sizeof(void*) = 64
boolProperty attributes: TB,N,V_boolProperty
obj.boolProperty = YES
[obj valueForKey:@"boolProperty"]: 1
[[obj valueForKey:@"boolProperty"] class]: __NSCFBoolean
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":true}
obj.boolProperty = NO
[obj valueForKey:@"boolProperty"]: 0
[[obj valueForKey:@"boolProperty"] class]: __NSCFBoolean
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":false}
代码:
@interface TSTObject : NSObject
@property (nonatomic, assign) BOOL boolProperty;
@end
[…]
NSLog(@"8 * sizeof(void*) = %lu", 8 * sizeof(void*));
objc_property_t boolProp = class_getProperty([TSTObject class], "boolProperty");
NSLog(@"boolProperty attributes: %s", property_getAttributes(boolProp));
void(^testBool)(BOOL) = ^(BOOL boolValue) {
TSTObject *obj = [[TSTObject alloc] init];
id vfk;
obj.boolProperty = boolValue;
vfk = [obj valueForKey:@"boolProperty"];
NSLog(@"obj.boolProperty = %@", boolValue ? @"YES" : @"NO");
NSLog(@"[obj valueForKey:@\"boolProperty\"]: %@", vfk);
NSLog(@"[[obj valueForKey:@\"boolProperty\"] class]: %@", [vfk class]);
NSLog(@"JSON serialization of @{ @\"boolProperty\": [obj valueForKey:@\"boolProperty\"] }: %@",
[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:@{@"boolProperty": vfk}
options:0
error:NULL]
encoding:NSUTF8StringEncoding]);
};
testBool(YES);
testBool(NO);
这些都是 Xcode 7.2,iOS 9.2 模拟器。
引述 this answer:
的根本原因似乎很可能是
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.
是这个原因吗?
这是错误还是预期的行为?
是的,就是这个原因。
是的,这是有意为之的行为。 (好吧,它在 32 位上序列化为 JSON 的方式并不是特别 "intended" 但它是预期的。64 位使用适当的 Bool 类型的事实是有意的。)
JSON 序列化程序无法区分单字节有符号整数和 32 位布尔值之间的区别,因为它们实际上是相同的东西。
似乎 valueForKey:
具有 BOOL
@property
键的名称 returns 不同的类型(因此,导致不同的 JSON 序列化) 在 64 位和 32 位 iOS 系统上:
在 32 位(iPhone 4s 模拟器上):
8 * sizeof(void*) = 32
boolProperty attributes: Tc,N,V_boolProperty
obj.boolProperty = YES
[obj valueForKey:@"boolProperty"]: 1
[[obj valueForKey:@"boolProperty"] class]: __NSCFNumber
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":1}
obj.boolProperty = NO
[obj valueForKey:@"boolProperty"]: 0
[[obj valueForKey:@"boolProperty"] class]: __NSCFNumber
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":0}
64 位(iPhone 6 模拟器):
8 * sizeof(void*) = 64
boolProperty attributes: TB,N,V_boolProperty
obj.boolProperty = YES
[obj valueForKey:@"boolProperty"]: 1
[[obj valueForKey:@"boolProperty"] class]: __NSCFBoolean
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":true}
obj.boolProperty = NO
[obj valueForKey:@"boolProperty"]: 0
[[obj valueForKey:@"boolProperty"] class]: __NSCFBoolean
JSON serialization of @{ @"boolProperty": [obj valueForKey:@"boolProperty"] }: {"boolProperty":false}
代码:
@interface TSTObject : NSObject
@property (nonatomic, assign) BOOL boolProperty;
@end
[…]
NSLog(@"8 * sizeof(void*) = %lu", 8 * sizeof(void*));
objc_property_t boolProp = class_getProperty([TSTObject class], "boolProperty");
NSLog(@"boolProperty attributes: %s", property_getAttributes(boolProp));
void(^testBool)(BOOL) = ^(BOOL boolValue) {
TSTObject *obj = [[TSTObject alloc] init];
id vfk;
obj.boolProperty = boolValue;
vfk = [obj valueForKey:@"boolProperty"];
NSLog(@"obj.boolProperty = %@", boolValue ? @"YES" : @"NO");
NSLog(@"[obj valueForKey:@\"boolProperty\"]: %@", vfk);
NSLog(@"[[obj valueForKey:@\"boolProperty\"] class]: %@", [vfk class]);
NSLog(@"JSON serialization of @{ @\"boolProperty\": [obj valueForKey:@\"boolProperty\"] }: %@",
[[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:@{@"boolProperty": vfk}
options:0
error:NULL]
encoding:NSUTF8StringEncoding]);
};
testBool(YES);
testBool(NO);
这些都是 Xcode 7.2,iOS 9.2 模拟器。
引述 this answer:
的根本原因似乎很可能是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.
是这个原因吗?
这是错误还是预期的行为?
是的,就是这个原因。
是的,这是有意为之的行为。 (好吧,它在 32 位上序列化为 JSON 的方式并不是特别 "intended" 但它是预期的。64 位使用适当的 Bool 类型的事实是有意的。)
JSON 序列化程序无法区分单字节有符号整数和 32 位布尔值之间的区别,因为它们实际上是相同的东西。