0

我有定义为这样火力地堡异步回调中的NSOperation不返回

import Foundation 

class ASyncOperation: NSOperation { 
    enum State: String { 
     case Ready, Executing, Finished 

     private var keyPath: String { 
      return "is" + rawValue 
     } 
    } 

    var state = State.Ready { 
     willSet { 
      willChangeValueForKey(newValue.keyPath) 
      willChangeValueForKey(state.keyPath) 
     } 
     didSet { 
      didChangeValueForKey(oldValue.keyPath) 
      didChangeValueForKey(state.keyPath) 
     } 
    } 

    override var ready: Bool { 
     return super.ready && state == .Ready 
    } 

    override var executing: Bool { 
     return super.ready && state == .Executing 
    } 

    override var finished: Bool { 
     return super.ready && state == .Finished 
    } 

    override var asynchronous: Bool { 
     return true 
    } 

    override func start() { 
     if cancelled { 
      state = .Finished 
      return 
     } 
     main() 
     state = .Executing 
    } 

    override func cancel() { 
     state = .Finished 
    } 
} 

一个AsyncOperation类和它ImageLoadOperation的子类。

import Foundation 
import UIKit 
import Firebase 

class ImageLoadOperation: ASyncOperation { 
    var imagePath: String? 
    var image: UIImage? 

    override func main(){ 
     let storage = FIRStorage.storage() 
     let storageRef = storage.referenceForURL("gs://salisbury-zoo- 91751.appspot.com") 
     if let path = imagePath { 
      let imageReference = storageRef.child(path) 
      imageReference.dataWithMaxSize(3 * 1024 * 1024) { (data, error) -> Void in 
      if (error != nil) { 
       self.image = nil 
      } else { 
       self.image = UIImage(data: data!) 
       self.state = .Finished 
      } 
     } 
    } 
    } 
} 

所以我去接听电话的运行队列中的

let queue = NSOperationQueue() 
    let imageLoad = ImageLoadOperation() 
    queue.addOperation(imageLoad) 

    let img:UIImage? = imageLoad.image 

但它总是返回零。当我在ImageLoadOperation的回调中放置打印语句时,图像在那里,并且状态设置为完成。当我添加

queue.waitUntilAllOperationsAreFinished() 

Inbetween queue.addOperation and let img:UIImage? = imageLoad.load,那么当主线程被阻塞时整个应用程序停止。关于如何让图像出现在回调范围之外的任何其他想法?我也尝试过没有NSOperationQueue,只是作为一个没有运气的NSOperation。

回答

1

queue.addOperation函数添加操作,并开始在后台线程中执行。因此在后台线程完成之前它会很好地返回,这就是图像为零的原因。

而且正如文档所述,waitUntilAllOperationsAreFinished会阻塞该线程直到操作完成。这在主线程中是非常不可取的。

imageReference.dataWithMaxSize是一个异步操作,它具有完成处理程序(您当前正在设置self.image)。你需要在那里触发代码来运行,这将允许你使用imageLoad.image。你如何做到这一点将取决于你的应用程序的架构。

例如,如果要将图像显示在UITableViewCell中,则需要将图像存储在图像数组中,可能位于索引与表格行匹配的位置,然后至少重新加载tableView的那一行。这是因为在图像被接收到时,该行可能不再存在该单元。显然你不希望这个代码坐在你的ImageLoadOperation类中。相反,它应该作为完成处理程序传入main()

+0

所以问题在这里概述http://stackoverflow.com/questions/36675986/asynchronous-callback-in-nsoperation-inside-of-nsoperationqueue-is-never-called。我的下一个问题是我如何让'imageReference.dataWithMaxSize'在队列线程中运行而不是主线程?它似乎即使我在我自己的队列和操作异步函数运行在主线程创建死锁。异步函数不应该在队列线程上运行吗? – Spothedog1