访问Alamofire中的错误会导致EXC_BAD_ACCESS

时间:2015-02-11 21:17:50

标签: ios swift alamofire

在我的iOS应用程序中,我有一个带有文本字段的UIVieController,每次编辑该值时都会发送一个请求。关键是要显示从服务器返回的用户建议作为JSON对象。 我最初让所有Alamofire请求都可以自由运行但是减轻了负载(即使这些请求非常轻量级)我添加了

didSet {
    oldValue?.cancel()
}

到我的控制器的modalRequest属性,该属性存储当前请求。

但是现在,我的响应处理程序在尝试访问闭包中的错误时抛出EXC_BAD_ACCESS(code = 1,address = 0x0)。代码如下:

@IBAction func textValueChanged(sender: AnyObject) {
    currentTextField = (sender as UITextField)

    if (currentTextField!.text != "") {
        modalRequest = Alamofire.request(.GET, "http://example.org/autocomplete/" + modalType.rawValue, parameters: ["term":currentTextField!.text]).responseJSON {(request, response, json, error) in
            if let error = error {
                NSLog("Error: \(error)")
                println(request)
                println(response)
            } else {
                let oldCount = self.suggestions.count
                self.suggestions.removeAll()
                let suggestionJSON = JSON(json!)
                for s in suggestionJSON.arrayValue {
                    self.suggestions.append(s["name"].stringValue)
                }
                self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
            }
        }
    } else {
        self.modalRequest?.cancel()
        self.suggestions.removeAll()
        self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
    }
}

奇怪和令人担忧的部分是,当我快速键入,从而取消未完成的请求时,一切都很快(双关语),这意味着控制台将所有错误记录为已取消。但是,如果我输入的文本包含空格并且通过快速键入取消了先前的请求,则记录器会尝试打印错误但抛出EXC_BAD_ACCESS,即使它处于可选绑定中!不应该确保价值不是零至少存在吗?

你有没遇到过这个?

感谢您的时间!

NB :删除该行当然有效,但我可能希望将来添加错误处理,这个错误确实让我烦恼

2 个答案:

答案 0 :(得分:0)

我认为你在两种可能的竞争条件下陷入困境。

  1. 以前的modalRequest
  2. 的deinit
  3. 自我弱化/强化问题
  4. 以下内容应解决两种竞争条件。

    @IBAction func textValueChanged(sender: AnyObject) {
        currentTextField = (sender as UITextField)
    
        if (currentTextField!.text != "") {
            modalRequest?.cancel()
            modalRequest = nil
    
            modalRequest = Alamofire.request(.GET, "http://example.org/autocomplete/" + modalType.rawValue, parameters: ["term":currentTextField!.text])
            modelRequest.responseJSON { [weak self] request, response, json, error in
                if let strongSelf = self {
                    if let error = error {
                        NSLog("Error: \(error)")
                        println(request)
                        println(response)
                    } else {
                        let oldCount = self.suggestions.count
                        self.suggestions.removeAll()
                        let suggestionJSON = JSON(json!)
                        for s in suggestionJSON.arrayValue {
                            self.suggestions.append(s["name"].stringValue)
                        }
                        self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
                    }
                }
            }
        } else {
            self.modalRequest?.cancel()
            self.suggestions.removeAll()
            self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Automatic)
        }
    }
    

    如果这最终起作用,那么我建议移动以下内容:

    modalRequest?.cancel()
    modalRequest = nil
    

    改为willSet而不是didSet

    willSet {
        modalRequest?.cancel()
    }
    

答案 1 :(得分:0)

为了继续我之前关于cnoon答案的评论:我用NSLog()替换了println()并且瞧!有用!没有更多的EXC_BAD_ACCESS。

但是我不知道为什么这是一个糟糕的访问。 NSLog某种程度上是如此之慢还是没有复制值,所以当它最终记录时它是零?我不知道......

编辑:正如我在我的问题中所说,当查询包含空格时,崩溃。而error.description(按原样添加到字符串中)包含URL String。在URL中编码的空格是“%20”,因此NSLog将其解释为字符串格式化程序%2,因此它在NSLog中寻找第二个可选参数,当然,不存在!哈哈!所以要真正精心修复它,我用以下代码替换了行:

NSLog("Error: %@", error)

现在它是一个美丽的日志,没有任何打嗝!这就是我复制一些默认代码所得到的,它将Swift字符串插值与Objective-C字符串格式组合在一起!