2014-09-29 14 views
8

Dzisiaj spotkałem jeden dziwny problem, kiedy próbowałem "uogólnić" moje "operacje importowania danych CoreData". Okazało się, że jeśli utworzę ogólną podklasę operacji NSOperation, funkcja 01cnie zostanie wywołana.Ogólna podklasa NSOperation traci funkcjonalność NSOperation

Prosty przykład:

class MyOperation<T: NSObject>: NSOperation { 

    override func main() { 
     println("My operation main was called") 
    } 
} 

Jeśli utworzyć wystąpienie tej klasy i dodać go do operationQueue widać, że to nie jest faktycznie main() nazywa.

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    self.operationQueue = NSOperationQueue() 
    let operation = MyOperation<NSString>() 
    self.operationQueue!.addOperation(operation) 
} 

Operacja prostu tranzytem z ready do executing i finished stanie bez wywoływania main().

Po usunięciu ogólnej adnotacji <T: NSObject> z klasy MyOperation będzie działać poprawnie.

Jak to jest możliwe? Czy tu czegoś brakuje?

Odpowiedz

7

Problem jest spowodowany tym prosta zasada:

Sposób ogólnej klasie nie może być reprezentowana w Objective-C

W rezultacie, gdy mostkiem do Objective-C, MyOperation wygląd tak jak czysty, bez żadnych metod, podklasa NSOperation.

Ten błąd można zobaczyć, oznaczając override func main() atrybutem @objc.

@objc override func main() { // < [!] Method in a generic class cannot be represented in Objective-C 
    println("My operation main was called") 
} 
+1

Dziękuję za wyjaśnienia. To smutne, że nie możemy używać tak potężnej techniki w Swift z Objective-C. W tym szczególnym przypadku "uogólnione" operacje mogą pomóc w ponownym wykorzystaniu kilku partii kodu. Cóż, tak. :/ – Nevs12

12

Obejście: Można utworzyć podklasę (bez NSOperation ogólne), zastąpić główny i nazywają jesteś właścicielem „wykonać” func, które mogą być nadpisane przez podklasy generycznych. Przykład:

class SwiftOperation : NSOperation { 

    final override func main() { 
     execute() 
    } 

    func execute() { 
    } 

} 

class MyOperation<T> : SwiftOperation { 

    override func execute() { 
     println("My operation main was called") 
    } 

} 
+0

Awesome, thanks! Bardzo przydatne także dla delegatów UIKit! – Ixx

+0

Używam tej metody do implementacji ogólnej tabelaViewDataSource – banxi1988

1

W Xcode 7 generic NSOperation został ustalony: jeśli ten kod na placu zabaw to działa:

protocol SomeProtocol { 

    // markup protocol 
} 

class GenericOperation<SomeTypeImplementingProtocol: SomeProtocol>: NSOperation { 

    let referenceToSomeTypeImplementingProtocol: SomeTypeImplementingProtocol 

    init(referenceToSomeTypeImplementingProtocol: SomeTypeImplementingProtocol) { 

     self.referenceToSomeTypeImplementingProtocol = referenceToSomeTypeImplementingProtocol 
    } 

    override func main() { 

     debugPrint("The GenericOperation main() method was called.") 

    } 
} 

class TypeImplementingSomeProtocol: SomeProtocol { 


    init() { 

    } 
} 


let operationQueue = NSOperationQueue() 

let typeImplementingSomeProtocolInstance = TypeImplementingSomeProtocol() 


let operation = GenericOperation<TypeImplementingSomeProtocol>(referenceToSomeTypeImplementingProtocol: typeImplementingSomeProtocolInstance) 


operationQueue.addOperation(operation) 
Powiązane problemy