In Swift, qualcosa come il seguente dovrebbe compiere il proprio compito, ma è diverso rispetto al suo omologo objC:
typealias GPUImageOutput = UIImage
@objc protocol GPUImageInput {
func lotsOfInput()
}
class GPUImageOutputWithInput: GPUImageOutput, GPUImageInput
{
func lotsOfInput() {
println("lotsOfInput")
}
}
// ...
var someGpuImage = GPUImageOutput()
var specificGpuImage = GPUImageOutputWithInput()
for image in [someGpuImage, specificGpuImage] {
if let specificImage = image as? GPUImageInput {
specificImage.lotsOfInput()
} else {
println("the less specific type")
}
}
UPDATE: ora che ho capito dove/perché si dispone di questi tipi ...
GPUImage sembra avere un esempio veloce che fa quello che si vuole, come Swift-ly possibile.
Vedi here:
class FilterOperation<FilterClass: GPUImageOutput where FilterClass: GPUImageInput>: FilterOperationInterface {
...
Il type constraint syntax può essere applicato alle funzioni, anche, e con un where clause, che è probabilmente buono come avete intenzione di arrivare direttamente a Swift.
Più ho cercato di capire come portare questo trucchetto objc un po 'comune, più ho capito che era il modo più rapido. Una volta visto l'esempio in GPUImage stesso, ero convinto che fosse almeno la tua risposta. :-)
UPDATE 2: Quindi, oltre l'esempio GPUImage specifica ho linkato sopra che utilizza Swift, più e più penso a questo, sia utilizzando una clausola where
a guardia della funzione setter, o utilizzando una proprietà calcolabile per filtrare la funzionalità set
sembra l'unico modo per andare.
sono arrivato fino a questa strategia:
import Foundation
@objc protocol SpecialProtocol {
func special()
}
class MyClass {}
class MyClassPlus: MyClass, SpecialProtocol {
func special() {
println("I'm special")
}
}
class MyContainer {
private var i: MyClass?
var test: MyClass? {
get {
return self.i
}
set (newValue) {
if newValue is SpecialProtocol {
self.i = newValue
}
}
}
}
var container = MyContainer()
println("should be nil: \(container.test)")
container.test = MyClass()
println("should still be nil: \(container.test)")
container.test = MyClassPlus()
println("should be set: \(container.test)")
(container.test as? MyClassPlus)?.special()
Uscite:
should be nil: nil
should still be nil: nil
should be set: Optional(main.MyClassPlus)
I'm special
(Opzionalmente, si potrebbe anche usare precondition(newValue is SpecialProtocol, "newValue did not conform to SpecialProtocol")
al posto del controllo is
, ma che agirà come un assert()
può Arresta l'app in caso di mancata corrispondenza. Dipende dalle tue esigenze.)
La risposta di @ rintaro è buona, ed è un buon esempio di utilizzo di un where
clausola come guardia (sia piacevole funzionale, che Swift-ly). Tuttavia, odio solo scrivere una funzione setFoo()
quando esistono proprietà computabili. Inoltre, anche l'uso di una proprietà computabile ha odore di codice, dal momento che non sembra possibile applicare un vincolo di tipo generico a set
e dobbiamo eseguire il test di conformità del protocollo in linea.
ho chiesto la stessa cosa qui: http://stackoverflow.com/questions/24455327/how-do-i-specify-that-a-non-generic-swift-type-should- conforme al protocollo, per gli stessi motivi –