2015-02-05 13 views
6

pracuję z Observer API (ObserverSet), które mają następujące funkcje:Swift - częściowe zastosowanie funkcji z rodzajowych

public func add<T: AnyObject>(object: T, _ f: T -> Parameters -> Void) -> ObserverSetEntry<Parameters> 

To po prostu zarejestrować object następnie wywołać metodę instancji f na object gdy powiadomień wyzwala

W jednym z moich menedżerów muszę ukryć poprzednią funkcję z jedną z moich, więc mogę zmusić obserwatora do wywołania funkcji predefiniowanej zaimplementowanej za pośrednictwem protokołu.

Oto co zrobiłem do tej pory:

@objc protocol Observer : NSObjectProtocol { 
    func observe(param: String) -> Void 
} 

func addObserver<T: AnyObject where T: Observer>(observer: T) { 
    let f: T -> String -> Void = observer.dynamicType.observe 
    entries.addObserver(observer, f) 
} 

Niestety, mam następujący błąd pokazuje się Partial application of generic method is not allowed

Znalazłem ewentualnego obejścia gdzieś na SO które wyglądają tak:

let f: T -> String -> Void = { (obs: T) in obs.dynamicType.observe(obs) } 

Ale ta linia kodu napędza mój XCode szalony z pewnym Segmentation Fault: 11 na kompilacji (i Communication interrupted z Playground ..)

Czy istnieje jakieś obejście tego, co próbuję zrobić?

+0

Co stanie się, jeśli zadeklarujesz swój protokół jako czysty protokół Swift, zamiast degradować go do protokołu objc? – augustzf

+0

Dokładny ten sam błąd. Jeśli również usunę implementację 'NSObjectProtocol', otrzymam' error: 'T' nie jest podtypem 'inout T'' – Yaman

Odpowiedz

4

nie testowałem, ale można spróbować:

@objc protocol Observer : NSObjectProtocol { 
    func observe(param: String) -> Void 
} 

func addObserver<T: AnyObject where T: Observer>(observer: T) { 
    let f: T -> String -> Void = { ($0 as AnyObject).observe } 
    entries.addObserver(observer, f) 
} 

Przynajmniej ten kompiluje ponieważ AnyObject posiada wszystkie metody z ObjC - w tym @objc - zajęcia/protokołów, jak ImplicitlyUnwrappedOptional.

Tak, to kompiluje:

let str = NSString(string: "test") 
(str as AnyObject).observe("foo") 

Oczywiście powoduje to błąd runtime ponieważ NSString ma observe(_:) metody. Ale w twoim przypadku, T ma gwarantowane Observer, powinno działać.

+0

Yay! Ta obsada to zrobiła. Ale nie rozumiem, dlaczego bez tego mam usterkę segmentacji? '' już mówi, że 'T' jest prawą' AnyObject'? Możliwy błąd? – Yaman

+0

Zderzenie samego Segfaulta to z pewnością błąd. Ale nie jestem pewien co do wymogu rzucania, może to ograniczenie języka. Jeśli tak, kompilator powinien zgłosić odpowiedni komunikat o błędzie. – rintaro

Powiązane problemy