【问题标题】:Found nil when unwrapping non nil value展开非 nil 值时发现 nil
【发布时间】:2015-04-27 07:36:20
【问题描述】:

我正在尝试通过以下参数快速发出获取请求

var dict = [
    "id_struttura" : 2,
    "prenCheck" : [
        "codice" : "14:30_15:20_1_3831_0",
        "id_sport" : 6,
        "ora_fine" : "20/02/2015 15:20:00",
        "ora_inizio" : "20/02/2015 14:30:00",
        "rec" : 0,
        "soci" : [
            [
                "esterno" : 0,
                "id" : "1980"
            ],
            [
                "esterno" : 0,
                "id" : "51"
            ]
        ]
    ]
]

使用以下方法:

private func genericRequest(method: Methods, url: String, data: [String: AnyObject]?) -> AnyObject?{
    var getRequest : NSURLRequest?
    var postRequest : NSMutableURLRequest?

    if method == Methods.GET{
        var completeUrl = url

        if(data != nil){
            //println(data)
            completeUrl += "?"
            for (key, value) in data! {

                completeUrl += "\(key)=\(value)&"
            }
            completeUrl = completeUrl.substringToIndex(completeUrl.endIndex.predecessor())
        }
        //println(completeUrl)

        let url = NSURL(string: completeUrl)
        getRequest = NSURLRequest(URL: url!)

    }else if method == Methods.POST{
        postRequest = NSMutableURLRequest(URL: NSURL(string: url)!)
        var session = NSURLSession.sharedSession()
        postRequest!.HTTPMethod = "POST"

        var params : String = ""

        for (key, value) in data! {

            params += "\(key)=\(value)&"
        }
        params = params.substringToIndex(params.endIndex.predecessor())

        var err: NSError?
        postRequest!.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding);
    }

    var response: NSURLResponse? = nil
    var error: NSError? = nil
    var request = getRequest != nil ? getRequest! : postRequest!
    let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)

    //println((response as NSHTTPURLResponse).statusCode)
    let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
    var json: AnyObject? = convertDataToJSON(reply)
    return json
}

将其称为genericRequest(Method.GET ,url:url, data: dict)(因为 Method 只是一个枚举)它无法在发出 get 请求时解开 for (key,value)in data! 中的数据变量,但在发出 post 请求时可以。由于我只能使用获取此任务的请求(我正在处理一个糟糕的休息界面),有人可以帮助我吗?

更新: 我也试过if let data = data { ...,它在这条线上崩溃了,上面写着unexpectedly found nil while unwrapping an Optional value

【问题讨论】:

  • 您是否检查过该操作在服务器上是否可用?您是否尝试过 Curl 它或通过 http/Advanced Rest 客户端发送请求?
  • 您需要将 NSURLRequest 上的 .method 设置为您选择的方法,我认为 post 是默认方法,但如果您要使用 get 则 getRequest.method = "GET"
  • 是的,确实如此。服务端几乎接受了get中的所有请求
  • 也许我没有解释清楚,这段代码只是在第一个for (key, value) in data! 中崩溃,因为它发现 data = nil 不是。我认为这与连接无关
  • 我的意思是,这是一个 Xcode 错误 :)。实际的错误行不存在。这个问题似乎在 Xcode 6.3 Beta 中修复了,试试吧。

标签: ios swift null unwrap


【解决方案1】:

您使用了大量的力展开 (!)。您执行此操作的每个地方都是您向编译器承诺可选项永远不会为零的地方。在大多数地方,我认为您应该允许编译器通过使用其他处理可选项的方法(可选链接、nil 合并、映射等)来证明 nil 的安全性

在你的具体情况下,我不知道你为什么不这样做:

if let data = data {

代替:

if (data != nil) {

然后必须使用! 强制解包数据。

我最近bloggedtalked 介绍了在 Swift 中处理选项的工具,如果您想了解有关如何不强制展开的更多信息。

【讨论】:

  • 我试过了,但即使我使用if let data_ = data { ... 应用程序崩溃说“致命错误:在展开可选值时意外发现 nil”(即使我知道该变量不是 nil)
【解决方案2】:

为什么您没有像在 GET 方法中那样检查 POST 方法中的数据是否为零。我认为 post 方法是你试图解开 nil 的地方

if method == Methods.GET{
    var completeUrl = url

    // here you check if data is nil
    if(data != nil){
        //println(data)
        completeUrl += "?"
        for (key, value) in data! {

            completeUrl += "\(key)=\(value)&"
        }
        completeUrl = completeUrl.substringToIndex(completeUrl.endIndex.predecessor())
    }
    //println(completeUrl)

    let url = NSURL(string: completeUrl)
    getRequest = NSURLRequest(URL: url!)

}else if method == Methods.POST{
    postRequest = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    postRequest!.HTTPMethod = "POST"

    var params : String = ""
    //check here as well
    if data != nil{
        for (key, value) in data! {

            params += "\(key)=\(value)&"
        }
        params = params.substringToIndex(params.endIndex.predecessor())
    }

    var err: NSError?
    postRequest!.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding);
}

【讨论】:

  • 不,错误出现在 GET 方法中,因为这是一个私有方法,我制作了两个函数包装器:func getRequest(url: String, data: [String: AnyObject]?) -> AnyObject?{ return genericRequest(Methods.GET, url: url, data: data) }func postRequest(url: String, data: [String: AnyObject]) -> AnyObject?{ return genericRequest(Methods.POST, url: url, data: data) },因此无需检查 post 方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-17
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多