在我的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 :删除该行当然有效,但我可能希望将来添加错误处理,这个错误确实让我烦恼
答案 0 :(得分:0)
我认为你在两种可能的竞争条件下陷入困境。
以下内容应解决两种竞争条件。
@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字符串格式组合在一起!