Ios “可选类型的值”;“任何对象?”;没有拆开你想用的包装!或

Ios “可选类型的值”;“任何对象?”;没有拆开你想用的包装!或,ios,objective-c,swift,Ios,Objective C,Swift,我从服务器接收到一个JSON响应 do { let response = try NSJSONSerialization.JSONObjectWithData(data!,options:NSJSONReadinOptions.AllowFragments) let cityDetails = reponse["cityDetails"] if cityDetails!.isKindOfClass(NSArray) { } }catch { pri

我从服务器接收到一个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) 下面的代码正在执行相同的操作,但只需要展开一次。此外,它崩溃是因为结果恰好是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
}

通过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
强制展开变量是一件你应该尽可能避免的事情

另一个片段:

 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
}

通过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
强制展开变量是一件你应该尽可能避免的事情

另一个片段:

 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将包含响应中键“cityDetails”的未包装NSArray。如果任何结果都是null或不是NSArray,那么您将在else子句中结束。使用if-let或guard-let总是一个bool,如果它确实是可转换的,则返回true。总是问(as?)永远不要强制(as!)转换为not crash。如果“cityDetails”不是数组,它会崩溃吗,就像在你的回答中它转换为NSArray一样。我不知道你得到的是什么,你可以在调试器中看到,但我假设它也是NSArray,因为你也使用了它。这就是发生的情况:它将确保常量cityDetails将包含响应中键“cityDetails”的未包装NSArray。如果任何结果都是null或不是NSArray,那么您将在else子句中结束。使用if-let或guard-let总是一个bool,如果它确实是可转换的,则返回true。始终要求(as?)从不强制(as!)转换为不崩溃。不,您应该使用guard(guard let result=result)打开结果,然后您可以始终安全地调用它。在gaurd let细节未打印出来后,出现了一些错误语句替换结果!。isKindOfClass(NSArray)和详细信息。isKindOfClass(NSArray),它是未包装的值。但我想这应该行得通,你还有问题吗?是的。在调用语句之前,但“详细信息检查之后”不会打印出来。此外,我还尝试了以下方法,但无法使用guard let details=result where details.isKindOfClass(NSArray)。我参考了这个链接。其中,gaurd将变量名称作为输入。如果您在上面添加打印(“转换失败”),则返回false。那会打印吗?如果是这种情况,请在返回false和返回true时为调试器设置断点,然后可以看到如果调试器未转换,则需要的详细信息。否,应使用guard(guard let result=result)打开结果然后你就可以放心地打电话给它了。高德让细节不被打印出来后,一些错误的陈述取代了结果!。isKindOfClass(NSArray)和详细信息。isKindOfClass(NSArray),它是未包装的值。但我想这应该行得通,你还有问题吗?是的。在调用语句之前,但“详细信息检查之后”不会打印出来。此外,我还尝试了以下方法,但无法使用guard let details=result where details.isKindOfClass(NSArray)。我参考了这个链接。其中,gaurd将变量名称作为输入。如果您在上面添加打印(“转换失败”),则返回false。那会打印吗?如果是这种情况,请在return false和return true处为调试器设置一个断点,然后您可以看到如果调试器不转换,则实际需要的详细信息。