Swift 中的 EXC_BAD_ACCESS 对自身的异步块调用崩溃
Asynchronous block call to self crashes with EXC_BAD_ACCESS in Swift
我有一个 API 调用(使用 AFNetworking),当失败时调用失败块。此块通过'self.refreshController.stopRefreshing(); 简单地停止table 视图刷新控制器;
但是在 运行 时,这会导致 EXC_BAD_ACCESS 错误。
failure: { (error: NSError!, reason: String!) -> Void in
self.refreshController.endRefreshing()
}
我已经尝试将调用放入 'dispatch_async' 主队列,但调用已经在主队列中,并且出现相同的错误。
failure: { (error: NSError!, reason: String!) -> Void in
dispatch_async(dispatch_get_main_queue())
{
self.refreshController.endRefreshing()
}
}
这让我相信问题与调用失败块时指向 'self' 的指针有关...我已经尝试过 'weak' 和 'unowned'自我,但这些不能解决它。
failure: { [weak self] (error: NSError!, reason: String!) -> Void in
self?.refreshController.endRefreshing()
}
欢迎任何想法。
更新:初始化
class ResultsViewController: UIViewController, UITableViewControllerDelegate, UITableViewControllerDataSource
{
var refreshController = UIRefreshControl()
override func viewDidLoad()
{
super.viewDidLoad()
// pull-to-refresh setup
self.refreshController.addTarget(self, action: "refreshTable:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(self.refreshController)
}
}
终于找到了根源。
我使用 AFNetworking 进行 API 调用,并创建了一个自定义失败块,其中包含 API 调用失败的原因。这是调用堆栈中的上链,但此错误似乎掩盖了它。 None 以上方法是必需的,但使用弱自方法确实帮助编译器在正确的文件中发现了问题。
问题可以追溯到这里:
两个块类型别名
typealias SuccessBlock = (responseArray: AnyObject!) -> Void
typealias FailureBlock = (error: NSError, reason: String) -> Void
AFNetworking POST 调用
private func post(url: String, inout parameters: [String : AnyObject], success: SuccessBlock, failure: FailureBlock)
{
self.sessionManager.POST(url,
parameters: parameters,
success: { (operation: NSURLSessionDataTask!, responseObject: AnyObject!) -> Void in
println("DEBUG: API POST Request to \(url) successful.")
var responses = responseObject as? [AnyObject]
success(responseArray:responses)
},
failure: { (operation: NSURLSessionDataTask!, error: NSError!) -> Void in
let reason = self.getResponseReasonFromError(error)
println("DEBUG: API GET Request to \(url) \nFailed: \(error). \nAPI Response: \(reason)")
failure(error: error, reason: reason)
}
)
}
错误出现在 FailureBlock 类型别名中
typealias FailureBlock = (error: NSError, reason: String) -> Void
typealias FailureBlock = (error: NSError, reason: String!) -> Void
缺少一个!在 String.
之后
我有一个 API 调用(使用 AFNetworking),当失败时调用失败块。此块通过'self.refreshController.stopRefreshing(); 简单地停止table 视图刷新控制器; 但是在 运行 时,这会导致 EXC_BAD_ACCESS 错误。
failure: { (error: NSError!, reason: String!) -> Void in
self.refreshController.endRefreshing()
}
我已经尝试将调用放入 'dispatch_async' 主队列,但调用已经在主队列中,并且出现相同的错误。
failure: { (error: NSError!, reason: String!) -> Void in
dispatch_async(dispatch_get_main_queue())
{
self.refreshController.endRefreshing()
}
}
这让我相信问题与调用失败块时指向 'self' 的指针有关...我已经尝试过 'weak' 和 'unowned'自我,但这些不能解决它。
failure: { [weak self] (error: NSError!, reason: String!) -> Void in
self?.refreshController.endRefreshing()
}
欢迎任何想法。
更新:初始化
class ResultsViewController: UIViewController, UITableViewControllerDelegate, UITableViewControllerDataSource
{
var refreshController = UIRefreshControl()
override func viewDidLoad()
{
super.viewDidLoad()
// pull-to-refresh setup
self.refreshController.addTarget(self, action: "refreshTable:", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(self.refreshController)
}
}
终于找到了根源。
我使用 AFNetworking 进行 API 调用,并创建了一个自定义失败块,其中包含 API 调用失败的原因。这是调用堆栈中的上链,但此错误似乎掩盖了它。 None 以上方法是必需的,但使用弱自方法确实帮助编译器在正确的文件中发现了问题。
问题可以追溯到这里:
两个块类型别名
typealias SuccessBlock = (responseArray: AnyObject!) -> Void
typealias FailureBlock = (error: NSError, reason: String) -> Void
AFNetworking POST 调用
private func post(url: String, inout parameters: [String : AnyObject], success: SuccessBlock, failure: FailureBlock)
{
self.sessionManager.POST(url,
parameters: parameters,
success: { (operation: NSURLSessionDataTask!, responseObject: AnyObject!) -> Void in
println("DEBUG: API POST Request to \(url) successful.")
var responses = responseObject as? [AnyObject]
success(responseArray:responses)
},
failure: { (operation: NSURLSessionDataTask!, error: NSError!) -> Void in
let reason = self.getResponseReasonFromError(error)
println("DEBUG: API GET Request to \(url) \nFailed: \(error). \nAPI Response: \(reason)")
failure(error: error, reason: reason)
}
)
}
错误出现在 FailureBlock 类型别名中
typealias FailureBlock = (error: NSError, reason: String) -> Void
typealias FailureBlock = (error: NSError, reason: String!) -> Void
缺少一个!在 String.
之后