2014-11-26 16 views
11

voglio catena un func a impl super, qualcosa di simile al seguenteCome chiamare eccellente in chiusura nel 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 
    }) 
    } 
    ... 
} 

l'errore di compilazione in realtà mi dice che il motivo chiaro: la chiusura non è un tipo di classe e non è permesso. Alla ricerca di qualsiasi suggerimento Come faccio a richiamare il metodo definito in super-classe?

+0

sento che questo è un bug, perché se 'self' è disponibile, allora' super' dovrebbe essere disponibile, in quanto 'super' è solo 'self' chiamato con un diverso schema di ricerca dei metodi. – newacct

+0

Ma lo schema di ricerca del metodo è "inizia a cercare sotto la classe a cui appartiene questo metodo" e quell'informazione non è presente nella chiusura. – gnasher729

risposta

16

Aggiornamento: partire dal Swift 1.2 b3, questo comportamento è corretto: il codice originale funziona come previsto. Yay, progresso!

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

Idealmente si potrebbe semplicemente scrivere:

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

Ma questo non funziona, semplicemente chiama self.myFunc(). I tweeted about this l'altro giorno e ho ottenuto un response from one of the Swift developers che si tratta di un bug noto. L'unica soluzione è quella di utilizzare un altro metodo per shuttle la chiamata a super:

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

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

Volevo dare a Nat e rintaro la risposta corretta. Dato che posso sceglierne solo uno, mi piace il nome che "kinda" suggerisce temporaneamente soluzione: per ora, lo chiamo: superMyFunc (per super.myFunc). Rintaro però ha il suo punto per la denominazione. Sicuramente, bello sapere che questo è un bug temporaneo. – Sean

+1

@Sean Funziona da Swift 1.2b3 :) –

5

Questa risposta potrebbe non rispondere alla tua domanda ..

Sorprendentemente, il seguente codice provoca infinita chiamata ricorsiva. Forse un bug?

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

L'unica soluzione che ho scoperto sta definendo un altro metodo:

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

Ma, credo, si dovrebbe usare un altro nome del metodo:

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