从 NSDictionary 设置时,BOOL 值从 NO 变为 Yes

Posted

技术标签:

【中文标题】从 NSDictionary 设置时,BOOL 值从 NO 变为 Yes【英文标题】:BOOL value changing from NO to Yes when setting up from NSDictionary 【发布时间】:2021-07-12 01:29:48 【问题描述】:

我有这个代码

if ([args valueForKey:@"showSetupScreen"]) 
    BOOL showSetupScreen = [args valueForKey:@"showSetupScreen"];
    NSLog(showSetupScreen ? @"YES" : @"NO");
    //  meetingConfig.showSetupScreen = showSetupScreen;

argsNSMutableDictionary

我字典中的args 值是NO,但是当我设置为BOOL showSetupScreen = [args valueForKey:@"showSetupScreen"]; 时,它变为YES

谁能帮助我理解为什么会发生这种情况。

附上截图供参考

【问题讨论】:

这能回答你的问题吗? valueForKey does not return the right value [args valueForKey:@"showSetupScreen"]return 一个NSNumber,所以showSetupScreen的值为NSNumber的地址,所以不能为NO。 【参考方案1】:

NSDictionary(或NSMutableDictionary)不能直接包含原始C 类型,例如BOOLNSDictionary 中的原始数字类型(包括布尔值)包装在 NSNumber 对象中。见Numbers Are Represented by Instances of the NSNumber Class 和Most Collections Are Objects。

因此,使用NSNumber方法boolValueNSNumber中提取布尔值,例如,

BOOL showSetupScreen = [[args valueForKey:@"showSetupScreen"] boolValue];

或者,更简单地说:

BOOL showSetupScreen = [args[@"showSetupScreen"] boolValue];

例如,原始 C 类型的示例,包括 BOOLNSIntegerdouble

NSDictionary *args = @
    @"foo": @NO,
    @"bar": @YES,
    @"baz": @42,
    @"qux": @3.14
;

BOOL foo = [args[@"foo"] boolValue];         // NO/false
BOOL bar = [args[@"bar"] boolValue];         // YES/true
NSInteger baz = [args[@"baz"] integerValue]; // 42
double qux = [args[@"qux"] doubleValue];     // 3.14

对于它的价值,如果您扩展 args 中包含的值,这将显示这些值的内部类型,您将看到与 showSetupScreen 关联的值(或我的 foo例如),不是BOOL,而是指向__NSCFBoolean/NSNumber的指针:

【讨论】:

【参考方案2】:

[args valueForKey:@"showSetupScreen"] 语句返回指针(内存中的地址),它有两个选项:某个地址(非零值)和NULL(零)。对于 C 编程语言,true 是任何非零值(在我们的例子中是内存中的任何地址)。出于这个原因,您在if 运算符和showSetupScreen 变量中得到true。但它只告诉你字典中有指定键的某个对象,而不是这个键的值(包装在这个对象中的值)。要获取此值(在我们的例子中为BOOL),您必须调用boolValue

【讨论】:

以上是关于从 NSDictionary 设置时,BOOL 值从 NO 变为 Yes的主要内容,如果未能解决你的问题,请参考以下文章

如何从NSDictionary数组中检查bool值

带有键值编码和 BOOL 的 JSONKit

NSDictionary 拒绝为其键设置值。

在从 NSDictionary 获取值时展开可选值时意外发现 nil

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc

不能使用 String 类型的索引为 NSDictionary 类型的值下标。从 Swift 2.3 -> 3.2 转换时