在Swift中使用EXC_BAD_ACCESS的异步块调用自身崩溃

时间:2015-02-03 14:44:46

标签: ios swift afnetworking

我有一个API调用(使用AFNetworking),当失败时调用失败块。该块只需通过&self; refreshController.stopRefreshing();停止表视图刷新控制器; 但是在运行时,这会导致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()
                }
        }

这让我相信这个问题与指向“自我”的指针有关。在调用故障块的时候......我已经尝试过“弱”了。并且'拥有者'自我,但这些都没有解决它。

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) 
    } 
}

1 个答案:

答案 0 :(得分:1)

最终找到了根本原因。

我正在使用AFNetworking进行API调用,并创建了一个自定义失败块,其中包括API调用失败的原因。这是调用堆栈中的链,但这个错误似乎掩盖了它。上述方法都不是必需的,但使用弱自我方法确实有助于编译器在正确的文件中找到问题。

问题可以追溯到这里:

两个块类型别名

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)
        }
    )
}

ErrorBlock类型别名

中出现错误
typealias FailureBlock = (error: NSError, reason: String) -> Void
typealias FailureBlock = (error: NSError, reason: String!) -> Void

想念一个!在String之后。