Подтвердить что ты не робот

Как вызвать супер в закрытии в Свифте

Я хочу связать func с super impl, что-то вроде следующего

class BaseClass {
  func myFunc() {
    // do something
  }
}

class MyClass: BaseClass {
  override func myFunc() {
    self.myOtherFunc(completionHandler: {
      super.myFunc() // error: 'super' members cannot be referenced in a non-class type
    })
  }
  ...
}

Ошибка компиляции на самом деле говорит мне причину ясно: закрытие не является типом класса, и это недопустимо. Поиск любого предложения Как вызвать метод, определенный в суперклассе?

4b9b3361

Ответ 1

Обновление: По сравнению с Swift 1.2 b3 это поведение исправлено - исходный код работает по назначению. Yay, прогресс!

class BaseClass {
    func myFunc() {
        println("BaseClass.myFunc()")
    }
}

class MyClass: BaseClass {
    func myOtherFunc(c: () -> ()) {
        c()
    }

    override func myFunc() {
        println("MyClass.myFunc()")
        self.myOtherFunc {
            super.myFunc()
        }
    }
}

MyClass().myFunc()
// MyClass.myFunc()
// BaseClass.myFunc()

В идеале вы могли бы просто написать:

class MyClass: BaseClass {
  override func myFunc() {
    let superFunc = super.myFunc
    self.myOtherFunc(completionHandler: {
      superFunc()
    })
  }
}

Но это не работает, оно просто вызывает self.myFunc(). я в твиттере об этом, и получил ответ от одного из разработчиков Swift, что это известная ошибка, Единственным обходным решением является использование другого метода для переключения вызова на супер:

class MyClass: BaseClass {
  override func myFunc() {
    self.myOtherFunc(completionHandler: {
      self.callSuperMyFunc()
    })
  }

  func callSuperMyFunc() {
    super.myFunc()
  }
}

Ответ 2

Этот ответ может не отвечать на ваш вопрос.

Удивительно, что следующий код вызывает бесконечный рекурсивный вызов. Может быть, ошибка?

class MyClass: BaseClass {
    override func myFunc() {
        let superMyFunc = super.myFunc
        self.myOtherFunc(completionHandler: {
            superMyFunc() // this actually calls MyClass.myFunc
            return
        })
    }
}

// ALSO
class MyClass: BaseClass {
    override func myFunc() {
        let superMyFunc = BaseClass.myFunc(self as BaseClass)
        self.myOtherFunc(completionHandler: {
            superMyFunc() // this actually calls MyClass.myFunc
            return
        })
    }
}

Единственным обходным решением, которое я обнаружил, является определение другого метода:

class MyClass: BaseClass {
    override func myFunc() {
        self.myOtherFunc(completionHandler: {
            self.callSuperMyFunc()
            return
        })
    }
    func callSuperMyFunc() {
        super.myFunc()
    }
}

Но, я думаю, вы должны использовать другое имя метода:

class MyClass: BaseClass {
    func myFuncAsync() {
        self.myOtherFunc(completionHandler: {
            self.myFunc()
            return
        })
    }
}