Swift: селектор с возвратом закрытия @escaping EXC_BAD_ACCESS - PullRequest
0 голосов
/ 03 сентября 2018

Что я делал, так это то, что у меня есть функция, которая запрашивает данные у API, и когда ответ, который я разделяю на два условия, - это .success и .failure в качестве ответа по умолчанию от Alamofire. и я использую escape-замыкание, чтобы проверить, если ответ .success, я покажу что-то, в противном случае вернет ошибку пользователю. и он работал нормально, пока я не хочу поместить его в селектор, который нужно использовать 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 голосов
/ 03 сентября 2018

Проблема в том, что вы не можете делать то, что делаете. Селектор, который вы установили для UIRefreshControl и события «значение изменено», должен иметь очень специфическую подпись. Ознакомьтесь с разделом «Механизм целевого действия» документации UIControl.

Селектор должен принимать либо ноль, либо один, либо два параметра, и эти параметры могут быть только очень специфическими параметрами. Первый (если указан) должен быть ссылкой на элемент управления (sender). И второе (если предусмотрено) должно быть UIEvent.

Вы не можете создать отправителя, который принимает блок завершения. Это причина аварии. Один параметр рассматривается как элемент управления обновлением, но код обрабатывает его как замыкание, следовательно, ошибка EXC_BAD_ACCESS.

Учтите это, учитывая, что вы используете GetData, где передается обработчик завершения? Что обрабатывает результат обработчика завершения?

Учитывая, что ничто не может иметь дело с этим обработчиком завершения, просто измените GetData (который должен называться getData), чтобы не принимать никаких параметров, и удалите использование completion.

@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)
...