【问题标题】:Generic NSOperation subclass loses NSOperation functionality通用 NSOperation 子类失去 NSOperation 功能
【发布时间】:2014-11-23 17:01:11
【问题描述】:

今天我在尝试“概括”我的“CoreData 导入操作”时遇到了一个奇怪的问题。 看来,如果我创建 NSOperation 的通用子类,main() 函数将不会被调用。

简单示例:

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 转换到executingfinished 状态而不调用main()

如果我从MyOperation 类中删除通用注释&lt;T: NSObject&gt;,它将正常工作。

这怎么可能? 我在这里遗漏了什么吗?

【问题讨论】:

    标签: generics swift nsoperation nsoperationqueue


    【解决方案1】:

    解决方法:您可以创建 NSOperation 子类(非泛型),覆盖 main 并调用您自己的“执行”函数,它可以被泛型子类覆盖。 示例:

    class SwiftOperation : NSOperation {
    
        final override func main() {
            execute()
        }
    
        func execute() {
        }
    
    }
    
    class MyOperation<T> : SwiftOperation {
    
        override func execute() {
            println("My operation main was called")
        }
    
    }
    

    【讨论】:

    • 太棒了,谢谢!对于 UIKit 代表也非常有用!
    • 我用这个方法实现了一个通用的tableViewDataSource
    【解决方案2】:

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

    Objective-C 不能表示泛型类中的方法

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

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

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

    【讨论】:

    • 感谢您的澄清。遗憾的是,我们不能在 Swift 中使用 Objective-C 中如此强大的技术。在这种特殊情况下,“通用”操作可以帮助重用大量代码。嗯,是的。 ://
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多