在执行另一个块之前执行所有后台线程

时间:2016-04-24 10:17:23

标签: ios multithreading core-data semaphore background-thread

我正在尝试在Core Data中加载照片,但这需要一些后台线程,所以碰巧我的对象在没有照片的情况下保存在Core Data中,我得到的照片是零。我的小组的照片也是如此。

简而言之,在每次迭代中,我都会在Core Data中保存一个对象,并且保存的速度比加载Photo数据的速度快。

我尝试过信号量,障碍,群体......但没有一个有效。我当然做错了但我不知道是什么。如果有人可以帮助我,我会非常感激,已经有两个星期了,我正在努力解决同样的问题。这是我的简化版代码,完整版可以在下面访问:

// MARK - ViewDidLoad
override func viewDidLoad() {
    // This method is only called once, so you want to create any controls or arrays here
    super.viewDidLoad()

    // Verifying connectivity to internet
    if Reachability.isConnectedToNetwork() == true {

    // Getting data from Parse + getDataInBackgroundWithBlock

    }else{

    }
}


// MARK - Action of the login button
@IBAction func loginBtn_click(sender: AnyObject) {
    if usernameTxt.text == "" || passwordTxt.text == "" {
        self.displayAlert("Error", message: "Please enter a username and password")
    }else{

        // MARK - Login the user
        PFUser.logInWithUsernameInBackground(usernameTxt.text!, password: passwordTxt.text!) { (user, error) -> Void in

            if error == nil {

                let queue = dispatch_queue_create("com.karagan.app.queue", DISPATCH_QUEUE_CONCURRENT)

                dispatch_async(queue, { () -> Void in
                    self.getObjectsFromQueryWithAscendingOrder("Add", key: "user", value: userName, ascendingOrder: "added", completionHandler: { (objects1) -> Void in

                // Update of an array in background 

                    })
                })



                dispatch_async(queue, { () -> Void in

               // Update of an array in background

                })



                dispatch_async(queue, { () -> Void in
                    self.getObjectsFromQueryWithAscendingOrder("Group", key: "membersUsername", value: userName, ascendingOrder: "membersUsername", completionHandler: { (objects3) -> Void in

                 // Update of an array in background

                        // MARK - Adding all the users in Core data
                        for var i = 0; i < usersFromParseDataBase.count; i++ {

                            let entity = NSEntityDescription.entityForName("Users", inManagedObjectContext: self.managedObjectContext)
                            let newUser = Users(entity: entity!, insertIntoManagedObjectContext: self.managedObjectContext)
                            if self.arrayAddedUsers.contains(usersFromParseDataBase[i].username){

                // Saving new records in Core Data                  

                            }
                        }
                    })
                })

                dispatch_async(queue, { () -> Void in
                    self.getObjectsFromQueryWithDescendingOrder("Group", key: "membersUsername", value: userName, descendingOrder: "conversationUpdate", completionHandler: { (objects4) -> Void in

                            if array.count == 2 {

                    // Getting data in background - photo.getDataInbackgroundWithBlock                  

                                }
                            }else{

                // Getting data in background - photo.getDataInbackgroundWithBlock

                            }
                        }
                    })
                })

                dispatch_barrier_async(queue, { () -> Void in

        // Doing some stuff in background which needs the data from threads above 

                })

            }else{
                // Print error from loginWithUsernaemInBackground
            }
        }
    }
}

这是显示在日志中的内容,因此您可以清楚地看到在执行图片加载之前屏障已执行。

TEST 3 - interacting user has been saved to core data
Loading profile image
Loading profile image
Loading group image
Loading profile image
Loading profile image
9
5
Loading group image
Loading group image
Loading group image
Loading group image

事情是我以后需要这些数据用于其他操作。我的代码不一致。

1 个答案:

答案 0 :(得分:-1)

我认为你走在正确的轨道上。当我创建一个简单的程序并使用dispatch_barrier_async时,它可以完美地运行:

let queue = dispatch_queue_create("com.karagan.app.queue", DISPATCH_QUEUE_CONCURRENT)

dispatch_async(queue, { () -> Void in
    sleep(1)
    print("1")
})

dispatch_async(queue, { () -> Void in
    sleep(2)
    print("2")
})

dispatch_async(queue, { () -> Void in
    sleep(3)
    print("3")
})

dispatch_async(queue, { () -> Void in
    sleep(4)
    print("4")
})

dispatch_barrier_async(queue, { () -> Void in
    print("done")
})

输出:

1
2
3
4
done

我认为问题是dispatch_async没有等待PFFile.getDataInBackgroundWithBlock的调用完成:

photoFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
    if error == nil {
        self.arrayImageFiles.append(imageData!)
        print("Loading group image")
    }
})

尝试使用getDataInBackgroundWithBlockhttps://parse.com/docs/osx/api/Categories/PFFile%28Synchronous%29.html#/c:objc%28cs%29PFFile%28im%29getData :)的同步调用将所有来电切换到PFFile.getData

var imageData = photoFile.getData
if (imageData != nil) {
    self.arrayImageFiles.append(imageData!)
}

由于您已经异步执行此代码,因此不会出现任何性能问题。