访问 Alamofire 中的错误导致 EXC_BAD_ACCESS
Accessing the error in Alamofire causes EXC_BAD_ACCESS
在我的 iOS 应用程序中,我有一个带有文本字段的 UIVieController,它会在每次编辑值时发送请求。重点是显示从服务器作为 JSON 对象返回的用户建议。
我最初有所有 Alamofire 请求 运行 自由但为了减轻负载(即使这些请求是 非常 轻量级)我添加了
didSet {
oldValue?.cancel()
}
到我的控制器的 modalRequest
属性,它存储当前请求。
但是现在,我的响应处理程序在尝试访问闭包中的错误时抛出 EXC_BAD_ACCESS(代码=1,地址=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)
}
}
奇怪和令人担忧的部分是,当我快速键入时,从而取消未完成的请求,一切都会迅速进行(双关语意),这意味着控制台将所有错误记录为已取消。但是,如果我输入的文本包含 space 并且之前的请求通过快速键入被取消,记录器会尝试打印错误但会抛出 EXC_BAD_ACCESS、,即使它处于可选绑定中!难道不应该确保值不为零,所以至少存在吗?
你遇到过这种情况吗?
感谢您的宝贵时间!
注意:删除该行当然有效,但我可能想在将来添加错误处理,这个错误真的很烦我
我认为您陷入了两种可能的竞争条件。
- 上一个modalRequest的deinit
- 自我的弱化/强化问题
下面应该解决这两个竞争条件。
@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()
}
为了继续我之前对 cnoon 回答的评论:我用 println()
替换了 NSLog()
瞧!有用!没有更多 EXC_BAD_ACCESS.
但是我不知道为什么访问不好。 NSLog
是不是太慢了,或者它没有复制值所以当它最终记录时它是零?我不知道...
EDIT :正如我在问题中所说,当查询包含 space 时,它 仅 崩溃。 error.description 按原样添加到字符串中,包含 URL 字符串。在 URL 中编码的 space 是“%20”,因此 NSLog
将其解释为字符串格式化程序 %2
,因此它会在 [=13] 中寻找第二个可选参数=] 当然, 不存在 !哈哈!因此,为了真正完美地修复它,我将这一行替换为:
NSLog("Error: %@", error)
现在是一个漂亮的日志,没有任何问题!这就是我复制一些默认代码的结果,这些代码结合了 Swift 字符串插值和 Objective-C 字符串格式!
在我的 iOS 应用程序中,我有一个带有文本字段的 UIVieController,它会在每次编辑值时发送请求。重点是显示从服务器作为 JSON 对象返回的用户建议。 我最初有所有 Alamofire 请求 运行 自由但为了减轻负载(即使这些请求是 非常 轻量级)我添加了
didSet {
oldValue?.cancel()
}
到我的控制器的 modalRequest
属性,它存储当前请求。
但是现在,我的响应处理程序在尝试访问闭包中的错误时抛出 EXC_BAD_ACCESS(代码=1,地址=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)
}
}
奇怪和令人担忧的部分是,当我快速键入时,从而取消未完成的请求,一切都会迅速进行(双关语意),这意味着控制台将所有错误记录为已取消。但是,如果我输入的文本包含 space 并且之前的请求通过快速键入被取消,记录器会尝试打印错误但会抛出 EXC_BAD_ACCESS、,即使它处于可选绑定中!难道不应该确保值不为零,所以至少存在吗?
你遇到过这种情况吗?
感谢您的宝贵时间!
注意:删除该行当然有效,但我可能想在将来添加错误处理,这个错误真的很烦我
我认为您陷入了两种可能的竞争条件。
- 上一个modalRequest的deinit
- 自我的弱化/强化问题
下面应该解决这两个竞争条件。
@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()
}
为了继续我之前对 cnoon 回答的评论:我用 println()
替换了 NSLog()
瞧!有用!没有更多 EXC_BAD_ACCESS.
但是我不知道为什么访问不好。 NSLog
是不是太慢了,或者它没有复制值所以当它最终记录时它是零?我不知道...
EDIT :正如我在问题中所说,当查询包含 space 时,它 仅 崩溃。 error.description 按原样添加到字符串中,包含 URL 字符串。在 URL 中编码的 space 是“%20”,因此 NSLog
将其解释为字符串格式化程序 %2
,因此它会在 [=13] 中寻找第二个可选参数=] 当然, 不存在 !哈哈!因此,为了真正完美地修复它,我将这一行替换为:
NSLog("Error: %@", error)
现在是一个漂亮的日志,没有任何问题!这就是我复制一些默认代码的结果,这些代码结合了 Swift 字符串插值和 Objective-C 字符串格式!