2014-09-29 14 views
8

Hôm nay tôi đã gặp một vấn đề lạ khi tôi đang cố gắng 'tổng quát' các hoạt động nhập khẩu CoreData của tôi '. Có vẻ như nếu tôi tạo một lớp con chung của NSOperation, main() func sẽ không được gọi.Lớp phủ NSOperation chung mất chức năng NSOperation

đơn giản ví dụ:

class MyOperation<T: NSObject>: NSOperation { 

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

Nếu bạn tạo một thể hiện của lớp này và thêm nó vào operationQueue bạn sẽ thấy rằng nó main() không thực sự gọi.

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

Operation đơn giản quá cảnh ready-executingfinished nhà nước mà không gọi main().

Nếu tôi xóa chú thích chung chung <T: NSObject> khỏi lớp MyOperation, nó sẽ hoạt động tốt.

Làm cách nào có thể? Tôi có thiếu gì đó ở đây không?

Trả lời

7

Vấn đề là do quy tắc đơn giản này:

Phương pháp trong một lớp học chung không thể được đại diện trong Objective-C

Kết quả là, khi cầu nối để Objective-C, MyOperation vẻ như tinh khiết, không có phương pháp nào bị ghi đè, NSOperation phân lớp.

Bạn có thể thấy lỗi này bằng cách đánh dấu override func main() với thuộc tính @objc.

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

Cảm ơn bạn đã làm rõ. Thật đáng buồn là chúng ta không thể sử dụng kỹ thuật mạnh mẽ như vậy trong Swift với Objective-C. Trong trường hợp cụ thể này, các hoạt động 'tổng quát' có thể giúp tái sử dụng khá nhiều cụm mã. À vâng. :/ – Nevs12

12

Cách giải quyết: Bạn có thể tạo NSOperation lớp con (không chung chung), ghi đè lên chính và gọi cho bạn sở hữu 'thực hiện' func, có thể được overriden bởi lớp con chung. Ví dụ:

class SwiftOperation : NSOperation { 

    final override func main() { 
     execute() 
    } 

    func execute() { 
    } 

} 

class MyOperation<T> : SwiftOperation { 

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

} 
+0

Tuyệt vời, cảm ơn! Rất hữu ích cho các đại biểu UIKit! – Ixx

+0

Tôi sử dụng phương pháp này để triển khai một tableViewDataSource chung – banxi1988

1

Trong Xcode 7 generic NSOperation đã được cố định: nếu tôi chạy mã này trong một sân chơi hoạt động:

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) 
Các vấn đề liên quan