Инициализатор класса с параметром @escaping - PullRequest
1 голос
/ 03 апреля 2019

Я устанавливаю класс, который в идеале может хранить асинхронный метод для последующего использования.Я хотел бы передать функцию внутри инициализатора класса, но я столкнулся со странной проблемой компилятора.

Cannot convert value of type '(@escaping (Int) -> Void) -> ()' to expected argument type '((Int) -> Void) -> Void'

Если метод не экранирует / синхронизирует, это работает нормально.Компилятор также предлагает принудительно привести параметр as! (((Int) -> Void) -> Void).Дали этот выстрел, но он вылетел.

Вот пример, с которым я возился на детской площадке:

class NumberTwo {
    let numberTwoMethod: ((Int) -> Void) -> Void

    init(numberTwoMethod: @escaping ((Int) -> Void) -> Void) {
        self.numberTwoMethod = numberTwoMethod
    }

    func callNumberTwoMethod() {
        numberTwoMethod { myNum in
            print(myNum)
        }
    }
}

func getNumberTwoMethod(completion: @escaping (Int) -> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        completion(2)
    }
}

func getNumberTwoMethodSync(completion: (Int) -> Void) {
    completion(2)
}

NumberTwo(numberTwoMethod: getNumberTwoMethod) // error: cannot convert value of type '(@escaping (Int) -> Void) -> ()' to expected argument type '((Int) -> Void) -> Void'
NumberTwo(numberTwoMethod: getNumberTwoMethodSync) // Works

Любые предложения о том, что здесь происходит, или альтернативные способы хранения асинхронныхфункция как переменная в классе?

1 Ответ

2 голосов
/ 03 апреля 2019

Вы пропустили @escaping на внутреннем замыкании:

class NumberTwo {
    let numberTwoMethod: (@escaping (Int) -> Void) -> Void

    init(numberTwoMethod: @escaping (@escaping (Int) -> Void) -> Void) {
        self.numberTwoMethod = numberTwoMethod
    }

    func callNumberTwoMethod() {
        numberTwoMethod { myNum in
            print(myNum)
        }
    }
}

или слегка упрощено:

class NumberTwo {
    typealias CompletionHandler = (Int) -> Void
    let numberTwoMethod: (@escaping CompletionHandler) -> Void

    init(numberTwoMethod: @escaping (@escaping CompletionHandler) -> Void) {
        self.numberTwoMethod = numberTwoMethod
    }

    func callNumberTwoMethod() {
        numberTwoMethod { myNum in
            print(myNum)
        }
    }
}

Также обратите внимание, что это, вероятно, приведет к утечке памяти, так как weak где угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...