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.

之后