I have a very big problem. I use Parse cloud system. When i fetch images with using "dispatch_semaphore" from parse, the main thread is locked. However, i think, i don't use main thread when fetching images. Normally, the task should be executed order by section A,B,C then D but app locked in section B.
Thanks.
let semaphore1:dispatch_semaphore_t = dispatch_semaphore_create(0)
let semaphore2:dispatch_semaphore_t = dispatch_semaphore_create(0)
let userquery = PFQuery(className: "_User")
userquery.findObjectsInBackground().continueWithSuccessBlock { (task) -> AnyObject? in
let results = task.result as! NSArray
for objectarray in results
{
let object = objectarray as! PFObject
let username = object["username"] as! String
let userpictureThumbnail = object["userPhotoThumbnail"] as! PFFile
userpictureThumbnail.getDataInBackground().continueWithSuccessBlock({ (task2) -> AnyObject? in
let result = task2.result as! NSData
let image = UIImage(data: result)
let imageThumbnail = image
// Section C-) Below codes must be executed but main thread is locked by Section B.
Model.sharedInstance.friendsPictureModel.addItem(username,FriendImageThumbnail:imageThumbnail!)
dispatch_semaphore_signal(semaphore2)
return nil
})
// Section B-) Second, enter the below code . And lock main thread then app freezed.
dispatch_semaphore_wait(semaphore2, DISPATCH_TIME_FOREVER)
}
dispatch_semaphore_signal(semaphore1)
return nil
}
// Section A-) When the block("userquery.findObjectsInBackground().continueWithSuccessBlock") is executed, enter the below code firstly.
dispatch_semaphore_wait(semaphore1, DISPATCH_TIME_FOREVER)
// Section D-) Below codes must be executed in the last.
self.collectionview.reloadData()
You should not be using semaphores here. Your section A is (presumably) running on the main thread, and the wait will cause it to block until the semaphore is signalled.
You could remove all the semaphore code and just dispatch
self.collectionview.reloadData()onto the main thread in where semaphore2 is currently being signalled. However, you also have a problem that addItem is being called in the background, and it's probably not thread safe.On the assumption that your example is a simplification of your specific problem, you probably have some separation between the viewController and userquery (let's call it
findTheObjects. So at the moment you would have something like:In this case, you should pass in your own completion block, along the lines of:
This completion block would then be called from your Section C.