如何处理 NSNull 值

cds*_*per 0 objective-c ios

在 Objective C 中,一个常见的做法是经常放弃检查 nil,而是依赖消息 nil 静默失败的事实。

例如,要验证字符串:

if ([myString length] > 1) { // Short and sweet
Run Code Online (Sandbox Code Playgroud)

如果myString为 nil,则此检查将失败 - 正如预期的那样。与人们可能认为的正确实现相比,这是一个巨大的改进,明确检查零:

if (myString && [myString length] > 1) { // Redundant nil check
Run Code Online (Sandbox Code Playgroud)

但是,特别是在 Web API 的情况下,可以想象 myString 是相等的[NSNull null]——类似于 nil,但具有不同的行为。主要关注的是,消息传递 NSNull 会导致异常。例如,我们之前的简短解决方案将导致异常:

// Causes an exception, because [NSNull null] is an object
NSString *myString = (id)[NSNull null];
if ([myString length] > 1) { 
Run Code Online (Sandbox Code Playgroud)

更复杂的是,一个简单的 nil 检查实际上会通过,因为它[NSNull null]是一个有效的对象:

NSString *myString = (id)[NSNull null];
if (myString) { // Evals to YES
Run Code Online (Sandbox Code Playgroud)

因此,完全安全的唯一方法是通过调用一个方法来检查 NSNull进行常规的隐式 nil 检查:

if (myString != (id)[NSNull null] && [myString length] > 1) { // Short and sweet
Run Code Online (Sandbox Code Playgroud)

我的问题:这真的有必要吗?是否有一个更简洁的选项和更少的重复代码,我忽略了?事实上,我的结论是否正确?

gna*_*729 5

NSNull 对象通常会随着人们阅读包含空值的 JSON 文件而出现。

在这种情况下,提供空值的服务器有可能认为您应该做一些与没有值不同的事情。例如,如果你得到一个字典并且可能有一个字符串存储在某个键下,你可能会得到一个非零长度的字符串,你可能会得到一个空字符串,因为服务器向你发送了一个空字符串,你可能什么也得不到,因为服务器什么也没给你发送,或者你可能得到 [NSNull null] 因为服务器给你发送了一个空值。由您决定是否需要对空字符串、nothing 和 [NSNull null] 进行不同处理。

顺便说一句:我一直使用 NSDictionary 类的一些扩展,例如 - (NSString*)stringForKey,它将返回一个 NSString 或 nil,100% 保证。如果你这样做,你所有的错误检查都在一种方法中。你可以做一些事情,比如将 NSNumber 转换为 NSString,或将 NSNull 转换为 nil,或将 NSDictionary 等转换为 nil,并且再也不用担心了。当然,你需要检查它是否合适。