2014-06-22 8 views
8

Jak prawidłowo odwołać się do siebie w szybkim zamknięciu?Właściwe odwoływanie się do siebie w dispatch_async

dispatch_async(dispatch_get_main_queue()) { 
    self.popViewControllerAnimated(true) 
} 

pojawia się błąd:

Cannot convert the expression's type 'Void' to type 'UIViewController!"

Losowo Próbowałem:

dispatch_async(dispatch_get_main_queue()) {() 
    self.popViewControllerAnimated(true) 
} 

i to działało. Nie wiem, co robi extra()! Czy ktoś chce wyjaśnić? Dzięki!

+0

Zaakceptuj odpowiedź, jeśli jest poprawna, i przekaż ją, jeśli przekroczyła Twoje oczekiwania. – vrwim

Odpowiedz

4

Jest to ten sam problem jak ludzie działają w tych pytaniach:

What am I doing wrong in Swift for calling this Objective-C block/API call?

animateWithDuration:animations:completion: in Swift

Oto ogólna idea:

Z Swift książki: https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/Closures.html

Jedna z optymalizacji zamknięcia jest:

Implicit returns from single-expression closures

Tak więc, jeśli masz tylko jedną linię w swoim zamknięciu, wartość powrotu zamknięcia się zmienia. W takim przypadku popViewController powoduje zwrócenie kontrolera widoku. Dodając () do zamknięcia, po prostu zamknęliśmy go na dwa wiersze, a wartość zwracana nie jest już domniemana!

+0

Nie jestem pewien, czy to się liczy jako duplikat z powodu tego samego problemu. Jeśli tak, proszę zgłoś! – Jack

+0

Nie duplikat. –

0

Odpowiedziałem coś takiego kilka dni temu do powiązanej emisyjnej re: Swift „niejawny wartości zwracanej do zamknięcia pojedynczego wyrażenie”: animateWithDuration:animations:completion: in Swift

W tym przypadku, sposób popViewControllerAnimated zwraca UIViewController, który został pojawiło ze stosu: (https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instm/UINavigationController/popViewControllerAnimated :)

Nawet jeśli nie robisz nic jawnie z zwracaną wartością tej metody, Swift używa tej wartości (zwrócony UIViewController) jako wartości zwracanej dla zamknięcia - jednak zamknięcie oczekuje wartości zwrotu Void.

Po dodaniu dodatkowych paren (), w zasadzie dodałeś kolejną linię do zamknięcia, a ponieważ nie jest to już "zamknięcie pojedynczego wyrażenia", to nie jest już niejawne, zwraca wykryte UIViewController.

Społeczność w końcu zgodzi się na konwencję, która ma na to wpływ, ponieważ teraz, kiedy już się do niej zgłosiłem, opowiadam się za dodaniem do końca zamknięcia return() (ponieważ wyraźnie stwierdza ona zamiar, (1) zwarcie "niejawny powrót" poprzez dodanie innej instrukcji i (2) wyraźne zwrócenie oczekiwanego).