斯威夫特:带@转义闭包的选择器返回EXC_BAD_ACCESS

时间:2018-09-03 02:51:31

标签: ios swift exc-bad-access uirefreshcontrol

我一直在做的事情是我有一个函数,该函数从API请求数据,当我将响应分为两个条件时,将.success和.failure作为Alamofire的默认响应。并且我一直在使用转义转义来检查响应是否成功,我将显示一些内容,否则将向用户返回错误。直到我想将其放入需要使用UIRefresh的选择器中为止,它都运行良好。

这是我的代码:

获取数据功能:

@objc func GetData(completion: @escaping (Bool)->Void){
    Alamofire.request("\(ConstanClass.http)/api/order?token=\(ConstanClass.token)").responseJSON { response in
        switch response.result {
        case .success:
            if let value = response.result.value{
                let json = JSON(value)
                //Geting Json
                completion(true)
            }
        case .failure(let error):

            self.setErrorForm(self)
            self.hud.dismiss(animated: true)
            print(error)
            completion(false)
        }
    }
}

从选择器呼叫:

refresher.addTarget(self, action: #selector(MyOrderController.GetData(completion:)), for: UIControlEvents.valueChanged)

这是错误:

  

线程1:EXC_BAD_ACCESS(代码= 257,地址= 0x1a1b50997c9)

,并且此错误指向completion(true)中的.success

1 个答案:

答案 0 :(得分:1)

问题在于您无法做自己正在做的事情。您为UIRefreshControl和“值更改”事件设置的选择器必须具有非常特定的签名。请查看UIControl文档的“目标-行动机制”部分。

选择器必须采用零,一或两个参数,并且这些参数只能是非常特定的参数。第一个(如果提供)必须是对控件(sender)的引用。第二个(如果提供)必须是UIEvent

您无法创建需要完成块的发件人。这就是崩溃的原因。一个参数被视为刷新控件,但代码将其视为闭包,因此出现EXC_BAD_ACCESS错误。

考虑到这一点,考虑到您使用GetData,将完成处理程序传递到哪里?处理完处理程序的结果是什么?

鉴于没有什么可以处理此完成处理程序,只需更改GetData(应命名为getData)以不使用任何参数并删除completion的用法。 / p>

@objc func getData(){
    Alamofire.request("\(ConstanClass.http)/api/order?token=\(ConstanClass.token)").responseJSON { response in
        switch response.result {
        case .success:
            if let value = response.result.value{
                let json = JSON(value)
                //Geting Json
            }
        case .failure(let error):
            self.setErrorForm(self)
            self.hud.dismiss(animated: true)
            print(error)
        }
    }
}

并更新您的用法:

refresher.addTarget(self, action: #selector(getData), for: UIControlEvents.valueChanged)