问题描述
if ([args valueForKey:@"showSetupScreen"]) {
BOOL showSetupScreen = [args valueForKey:@"showSetupScreen"];
NSLog(showSetupScreen ? @"YES" : @"NO");
// meetingConfig.showSetupScreen = showSetupScreen;
}
其中 args
是 NSMutableDictionary
。
args
值是 NO
但是当我设置为 BOOL showSetupScreen = [args valueForKey:@"showSetupScreen"];
时它变成了 YES
谁能帮助我理解为什么会发生这种情况。
附截图供您参考
解决方法
NSDictionary
(或 NSMutableDictionary
)不能直接包含原始 C 类型,例如 BOOL
。 NSDictionary
中的原始数字类型(包括布尔值)包含在 NSNumber
对象中。请参阅 Numbers Are Represented by Instances of the NSNumber Class 和 Most Collections Are Objects。
因此,使用 NSNumber
方法 boolValue
从 NSNumber
中提取布尔值,例如,
BOOL showSetupScreen = [[args valueForKey:@"showSetupScreen"] boolValue];
或者,更简单:
BOOL showSetupScreen = [args[@"showSetupScreen"] boolValue];
例如,具有原始 C 类型的示例,包括 BOOL
、NSInteger
和 double
:
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
(或 { {1}} 在我的示例中),不是 foo
,而是指向 BOOL
/__NSCFBoolean
的指针:
[args valueForKey:@"showSetupScreen"]
语句返回指针(内存中的地址),它有两个选项:某个地址(非零值)和 NULL
(零)。对于 C 编程语言,true
是任何非零值(在我们的例子中是内存中的任何地址)。因此,您会在 true
运算符和 if
变量中获得 showSetupScreen
。但它只告诉你字典中存在某个指定键的对象,而不是这个键的值(包裹在这个对象中的值)。要获取此值(在我们的示例中为 BOOL
),您必须调用 boolValue
。