通用NSOperation子类失去了NSOperation功能

时间:2014-09-29 10:20:03

标签: generics swift nsoperation nsoperationqueue

今天,当我试图推广“#”时,我遇到了一个奇怪的问题。我的CoreData导入操作'。 似乎如果我创建一个NSOperation的通用子类,main() func就不会被调用。

简单示例:

class MyOperation<T: NSObject>: NSOperation {

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

如果您创建此类的实例并将其添加到operationQueue,您会发现它main()实际上并未被调用。

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

操作只需从ready转换为executing并转换为finished状态,而无需调用main()

如果我从<T: NSObject>类删除通用注释MyOperation,它将正常工作。

这怎么可能? 我在这里错过了什么吗?

3 个答案:

答案 0 :(得分:12)

解决方法:您可以创建NSOperation子类(不是通用的),覆盖main并调用您自己的'execute'func,它可以被泛型子类覆盖。 例如:

class SwiftOperation : NSOperation {

    final override func main() {
        execute()
    }

    func execute() {
    }

}

class MyOperation<T> : SwiftOperation {

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

}

答案 1 :(得分:7)

问题是由这个简单的规则引起的:

  

泛型类中的方法无法在Objective-C

中表示

因此,当桥接到Objective-C时,MyOperation看起来像纯粹的,没有覆盖任何方法,NSOperation子类。

您可以使用override func main()属性标记@objc来查看此错误。

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

答案 2 :(得分:1)

在Xcode 7中,通用的NSOperation已得到修复:如果我在游乐场中运行此代码,它可以工作:

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)