NSBlockOperation未执行

时间:2016-02-07 13:15:04

标签: swift asynchronous nsoperation

由于我正在处理Web服务调用和数据库检索,我偶然发现NSBlockOperation无法启动的问题。

但是,首先要解释一下事情。主要目标是拥有一个包含以下操作的操作队列:

  1. 操作#1 - 向Web服务发送请求以开始创建数据库.zip文件
  2. 操作#2 - 完成#1后,重复调用Web服务以获取.zip文件压缩过程的进度
  3. 操作#3 - 完成#2后,使用NSURLSessionDownloadTask下载数据库。
  4. 为此,我定义了以下类:

    class DatabaseServerDownload {
    typealias Callback = (storedLocation : NSURL) -> ()
    typealias Failure = ((error : NSError) -> Void)
    
    let callback : Callback
    let failure : Failure
    
    let operationQueue : NSOperationQueue
    
    required init(callback : Callback, failure : Failure) {
        operationQueue = NSOperationQueue()
        operationQueue.maxConcurrentOperationCount = 1
    
        self.callback = callback
        self.failure = failure
    }
    
    func start() {
        let databaseCreationOperation = createDatabaseOnServer()
        let databaseCheckOperation = repeatedlyCheckForDatabaseReadiness()
        let databaseDownloadOperation = downloadDatabaseFromServer()
    
        databaseCheckOperation.addDependency(databaseCreationOperation)
        databaseDownloadOperation.addDependency(databaseCheckOperation)
    
        operationQueue.addOperations([databaseCreationOperation, databaseCheckOperation, databaseDownloadOperation], waitUntilFinished: true)
    }
    
    func createDatabaseOnServer() -> BlockOperation {
        let operation : BlockOperation = BlockOperation()
        operation.addExecutionBlock({SVMRSendTask(method: BeginCreatingDatabase(), onSuccess: {operation.finish()}, onFailure: {e in}).apply()})
        return operation
    }
    
    func repeatedlyCheckForDatabaseReadiness() -> NSBlockOperation {
        return NSBlockOperation(block: {SVMRRequestTask(method: DatabaseZipReady()).apply(5, c: {s in s == "OK"}, f: {s in String(s)}, onSuccess: {r in}, onFailure: {e in})})
    }
    
    func downloadDatabaseFromServer() -> NSBlockOperation {
        let sourceURL : NSURL = RequestDatabaseIdentitiesForDownload.sharedInstance.databaseURL
        return NSBlockOperation(block: {DownloadTask(url: sourceURL, progressCallback: {p in}, successCallback: {l in}, failureCallback: {e in }).start()})
    }
    }
    

    SVMRRequestTask将Web服务方法作为参数(虽然该方法是抽象类SVMR的实例),然后使用NSURLSessionTasks执行Web服务请求。

    BlockOperation如下:

    class BlockOperation : NSBlockOperation {
    
    private var _isFinished : Bool = false
    private var _isExecuting : Bool = false
    
    override var finished : Bool {
        return _isFinished
    }
    
    override var executing : Bool {
        return _isExecuting
    }
    
    func finish() {
        if cancelled {
            return
        }
    
        self.willChangeValueForKey("ready")
        _isReady = false
        self.didChangeValueForKey("ready")
    
        self.willChangeValueForKey("executing")
        _isExecuting = false
        self.didChangeValueForKey("executing")
    
        self.willChangeValueForKey("finished")
        _isFinished = true
        self.didChangeValueForKey("finished")
    }
    }
    

    任何人都可以解释我到底做错了什么 - 因为我第一次使用NSOperation类。在此之前,我当然在Apple的整个文档中提到了其他一些参考资料,但不幸的是,找不到任何东西。

1 个答案:

答案 0 :(得分:3)

您可以通过NSBlockOperation来解决这个问题,这是通过添加依赖关系来执行序列化操作队列的最佳方法,

@dsafa我已经在gist中为你创建了一个样本: https://gist.github.com/prajwalabove/66eecbf6b6aa096d5e18b04bd0cc18e8