我怎么知道多线程何时完成(Swift)

时间:2015-06-03 22:03:48

标签: multithreading swift parse-platform

我使用Parse来获取行,每行包含PFFile。我想以这种方式将获取的数据存储到模型中:

class MyModel {
    var name: String
    var image: UIImage

    init(dataObject: PFObject) {
         self.name=dataObject["name"] as! String
         let imageFile = dataObject["image"] as! PFFile
         imageFile.getDataInBackgroundWithBlock() {
              (imageData: NSData?,error: NSError?) -> Void in
              self.image=UIImage(imageData)
         }
    }

}

func fetchData() {
    var myCollection = Array<MyModel>()
    parseQuery.findObjectsInBackgroundWithBlock {
         (objects: [AnyObject]?,error: NSError) -> Void in
         if let parseObjects = objects as? [PFObject] {
              for parseObject in parseObjects {
                   myCollection.append(MyModel(parseObject))
              }
         }
    }
    println("Fetching finished and data loaded")
}

那就是“完成了”#39;是正确的,但由于该图像提取仍然没有加载数据,在这种情况下如何获取提取和myCollection对象是否完全加载?

3 个答案:

答案 0 :(得分:2)

您可以使用 NSOperation + NSOperationQueue ,如下所示:

import Foundation

let queue = NSOperationQueue()
queue.maxConcurrentOperationCount = 1

for _ in 0..<10
{
    var op = NSBlockOperation( block: {
        println("do something")
    } )
    queue.addOperation( op )
}

queue.suspended = false
queue.waitUntilAllOperationsAreFinished()

println("done!")

答案 1 :(得分:0)

如果您只是担心一次调用,您可以使用观察者创建变量以继续计算待处理函数或带有观察者的简单布尔值,如下例所示:

等待一个请求完成:

var finishRequest:Bool{
    didSet{
        if finishRequestesFunc{
            finishReques() //call function when finish download request
        }
    }
}

等待许多请求完成:

var counthRequests:Int{
    didSet{
        if (counthRequests == 0) {
            finishRequestesFunc() //call function when finish download request
        }
    }
}

现在,您需要做的就是在调用请求函数finishRequest之前将false设置为(findObjectsInBackgroundWithBlock),并在完成后将其设置为true设置为true,将调用finishRequestesFunc函数。 类似于count方法,但是在这里你在调用请求函数(findObjectsInBackgroundWithBlock)之前添加一个并在完成后减去一个,当计数器返回到零时,函数finishRequestsFunc将被调用

class MyModel {
    var name: String
    var image: UIImage
    var finishRequest:Bool{
         didSet{
            if finishRequestesFunc{
                finishReques() //call function when finish download request
            }
        }
    }   
    init(dataObject: PFObject) {
         self.name=dataObject["name"] as! String
         let imageFile = dataObject["image"] as! PFFile
         imageFile.getDataInBackgroundWithBlock() {
              (imageData: NSData?,error: NSError?) -> Void in
              self.image=UIImage(imageData)
         }
    }

    func fetchData() {
        finishRequest = false
        var myCollection = Array<MyModel>()
        parseQuery.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]?,error: NSError) -> Void in
            [unowned self]
            if let parseObjects = objects as? [PFObject] {
                for parseObject in parseObjects {
                    myCollection.append(MyModel(parseObject))
                }
            }
            self.finishRequest = true
        }
        println("Fetching finished and data loaded")
    }

    func finishReques(){
    } 

答案 2 :(得分:0)

首先,一般答案:

Grand Central Dispatch有派遣小组的概念。有一些方法,如dispatch_group_create和dispatch_group_notify,可以让你跟踪一组块,并在组完成后触发一个单独的块。

但这似乎并不适用于您的问题,因为您正在使用第三方库(解析)。

我要做的是创建一个名为remainingTasks的实例变量。当您准备好开始需要在后台执行多项操作的任务时,请将其设置为需要运行的子任务的数量。在每个任务的完成处理程序中,减少计数。然后将@Set方法添加到实例变量中,如@IcaroNZ所示。一旦剩下的任务降到零,你就知道你已经完成了并且可以继续。