【问题标题】:Value of optional Type "AnyObject?" not unwrapped did you mean to use ! or?可选类型“AnyObject?”的值未打开您的意思是要使用!或者?
【发布时间】:2015-10-24 22:06:29
【问题描述】:

我正在接收来自服务器的 JSON 响应。

 do {
    let response = try NSJSONSerialization.JSONObjectWithData(data!,options:NSJSONReadinOptions.AllowFragments)
    let cityDetails  = reponse["cityDetails"]

    if cityDetails!.isKindOfClass(NSArray) {

    }
 }catch {
   println("Error \(error)")
 }

我收到以下消息

Value of optional Type "AnyObject?" not unwrapped did you mean to use ! or ??

我稍后添加的更正是使用 double !!。如果cityDetails!!.isKindOfClass(NSArray)

下面列出了两个问题来理解这一点?

1) 即使对象已经解包过一次,为什么还要再次解包。

2) 下面的代码做同样的事情,但只需要解包一次。此外,它崩溃是因为 result 恰好是 nil。在 Objectice C 中,nil 已经是句柄并且在这种情况下将返回 false,而不是使应用程序崩溃。在那个声明中。

let testDictionary:[String:AnyObject] = ["a",NSMutableArray()]
let result = testDictionary["C"]

if result.isKindOfClass(NSArray) {

}

输入后的答案 2)为了解决第二个问题,我使用以下代码。

方法 1

if let _ = result {

    if result.isKindOfClass(NSArray) {

    }
}

方法 2

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    let testDictionary:[String:AnyObject] = ["a":NSMutableArray()]

    let result = testDictionary["C"]

    print("Before details Check")
    guard let details = result where details.isKindOfClass(NSArray) else {
        return false
    }
    print("Returned Result \(details)")
    print("After Details Check")
    return true
}

【问题讨论】:

  • 不,你应该使用 guard (guard let result = result) 解开结果,然后你就可以安全地调用它了。
  • gaurd let details are not print out后出现错误声明
  • 将 result!.isKindOfClass(NSArray) 替换为 details.isKindOfClass(NSArray),这是展开后的值。但这应该可行,我想,你还有问题吗?
  • 是的。调用了之前的语句,但没有打印出“详细检查之后”。另外,我尝试了以下但没有工作守卫让详细信息=结果详细信息.isKindOfClass(NSArray)。我参考了这个链接stackoverflow.com/questions/30791488/swift-2-guard-keyword。其中 gaurd 具有可变名称作为输入。
  • 如果在上面添加 print("Conversion failed") 会返回 false。那个打印?如果是这种情况,在 return false 和 return true 处都为调试器设置断点,那么你可以看到想要的细节真的是如果它没有转换。

标签: ios objective-c swift


【解决方案1】:

通过 if letguard let 语句解包值:

guard let cityDetails = response["cityDetails"] as? NSArray else {
    // Something went wrong trying to turn response["cityDetails"] into an unwrapped NSArray
    return
}

// From this point cityDetails will be an unwrapped NSArray

变量的强制解包是你应该尽可能避免的事情。

另一个sn-p:

 guard let result = result  // Unwrap result
    where result.isKindOfClass(NSArray) else { // Ask the unwrapped value if it's an NSArray
    return // If one of above is not the case we shouldn't continue
}

【讨论】:

  • 如果“cityDetails”不是数组,它会崩溃吗,就像你的回答中它转换为 NSArray
  • 我不知道你得到了什么,你可以在你的调试器中看到,但我认为它是 NSArray,因为你也使用了它。这就是发生的事情:它将确保常量 cityDetails 将包含一个未包装的 NSArray,用于响应中的键“cityDetails”。如果任何结果为 null 或不是 NSArray,则您最终会出现在 else 子句中。如果确实是可转换的,则使用 if letguard let 始终是返回 true 的布尔值。总是问(as?)永远不要强迫(as!)转换不崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 2015-11-11
  • 1970-01-01
相关资源
最近更新 更多