【问题标题】:BOOL property KVC: is this behavior a bug?BOOL 属性 KVC:这种行为是错误吗?
【发布时间】:2016-06-16 01:06:14
【问题描述】:

在 64 位和 32 位 iOS 系统上,带有 BOOL @property 名称的 valueForKey: 似乎会返回不同的类型(因此会导致不同的 JSON 序列化):

在 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

备注: 在 64 位 iOS 平台上(但不在 64 位 OS X 上),BOOL 被定义为 C99 _Bool,这是一个“正确的”布尔类型并且只能取值 0 或 1。

是这个原因吗?

这是错误还是预期行为?

【问题讨论】:

    标签: ios objective-c boolean kvc


    【解决方案1】:

    是的,就是这个原因。

    是的,这是预期的行为。 (好吧,它在 32 位上序列化为 JSON 的方式并不是特别“有意”,但这是意料之中的。64 位使用正确的 Bool 类型这一事实是有意的。)

    JSON 序列化程序无法区分单字节有符号整数和 32 位布尔值之间的区别,因为它们实际上是相同的。

    【讨论】:

    • 最简单的解决办法可能是处理 NSNumber 实例包装原语,同时编码/解码 JSON。
    • 公平地说,32 位 iOS 上的 ObjC 运行时无法区分 BOOL 属性和 signed char 属性吗?
    • 这是正确的,因为它们是同一个东西。 BOOL 只是 32 位上 signed char 的类型别名。
    猜你喜欢
    • 2013-11-11
    • 2017-04-17
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    相关资源
    最近更新 更多