从 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;
args
是 NSMutableDictionary
。
我字典中的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 类型,例如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
关联的值(或我的 foo
例如),不是BOOL
,而是指向__NSCFBoolean
/NSNumber
的指针:
【讨论】:
【参考方案2】:[args valueForKey:@"showSetupScreen"]
语句返回指针(内存中的地址),它有两个选项:某个地址(非零值)和NULL
(零)。对于 C 编程语言,true
是任何非零值(在我们的例子中是内存中的任何地址)。出于这个原因,您在if
运算符和showSetupScreen
变量中得到true
。但它只告诉你字典中有指定键的某个对象,而不是这个键的值(包装在这个对象中的值)。要获取此值(在我们的例子中为BOOL
),您必须调用boolValue
。
【讨论】:
以上是关于从 NSDictionary 设置时,BOOL 值从 NO 变为 Yes的主要内容,如果未能解决你的问题,请参考以下文章
在从 NSDictionary 获取值时展开可选值时意外发现 nil
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc
不能使用 String 类型的索引为 NSDictionary 类型的值下标。从 Swift 2.3 -> 3.2 转换时