2014-11-26 9 views
11

Chcę łańcucha FUNC do Super IMPL, coś w następującyjak wywołanie super w zamknięciu w Swift

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

Błąd kompilacji rzeczywiście mówi mi powód wyraźnie: zamknięcie nie jest to typ klasy i nie jest dozwolone. Szukasz jakiejkolwiek sugestii Jak mogę wywołać metodę zdefiniowaną w super klasie?

+0

Czuję, że to błąd, ponieważ jeśli 'self' jest dostępny, to' super' powinno być dostępne, ponieważ 'super' jest tylko 'self' wywoływane z innym schematem wyszukiwania metod. – newacct

+0

Jednak schemat wyszukiwania metod "zaczyna wyglądać poniżej klasy, do której należy ta metoda", a ta informacja nie znajduje się w zamknięciu. – gnasher729

Odpowiedz

16

Aktualizacja: dzień Swift 1.2 b3, to zachowanie jest naprawione - oryginalny kod działa zgodnie z przeznaczeniem. Yay, postęp!

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

Idealnie można po prostu napisać:

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

Ale to nie działa, to po prostu wywołuje self.myFunc(). I tweeted about this innego dnia i dostałem response from one of the Swift developers, że jest to znany błąd. Jedynym sposobem obejścia tego problemu jest użycie innej metody przełączania połączenia na super:

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

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

Chciałem dać Nat i rintaro obu poprawnej odpowiedzi. Ponieważ mogę wybrać tylko jedną, lubię nazwę, która "kinda" sugeruje tymczasowe obejście: na razie, nazywam ją: superMyFunc (dla super.myFunc). rintaro ma swój punkt na nazwę. Zdecydowanie dobrze jest wiedzieć, że to tymczasowy błąd. – Sean

+1

@Sean Działa jak Swift 1.2b3 :) –

5

Ta odpowiedź może nie odpowiadając na pytanie ..

Niespodziewanie, poniższy kod powoduje nieskończoną rekurencyjne wywołanie. Może błąd?

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

Jedyne obejście się dowiedziałem jest określenie innego sposobu:

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

Ale, jak sądzę, należy użyć innej nazwy metoda:

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