2016-01-28 12 views
0

У меня очень большая проблема. Я использую облачную систему Parse. Когда я получаю изображения с использованием «dispatch_semaphore» из синтаксического анализа, основной поток блокируется. Однако, я думаю, я не использую основной поток при извлечении изображений. Как правило, задача должна выполняться по порядку по разделам A, B, C, затем D, но приложение заблокировано в разделе B.Основной поток заблокирован при выборе изображений из синтаксиса с помощью семафора

Спасибо.

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() 
+1

Вы вызываете 'dispatch_sempahore_wait' в основной теме? Если да, не следует ли переместить его в фоновый поток, если вы не хотите блокировать основной поток? как и в, переместить всю задачу (создание и ожидание sempahore) на вторичный поток. – ishaq

+0

Есть ли где-то, что рекомендует использовать семафоры? На уровне поверхности я не удивлен, что у вас есть блокировка основного потока, так как это то, что предназначены семафорам. Если вы знаете, что выбор синтаксического анализа происходит в фоновом режиме, вместо этого я бы выполнил свой блок завершения dispatch_async обратно в основной поток, вызывающий 'reloadData()'. –

ответ

0

Вы не должны использовать семафоры здесь. Ваш раздел A (предположительно) работает в основном потоке, и ожидание приведет к его блокировке до тех пор, пока не будет сигнализирован семафор.

Вы можете удалить весь код семафора и просто отправить self.collectionview.reloadData() на главный поток, где в настоящее время сигнализируется семафор2. Однако у вас также возникла проблема с тем, что addItem вызывается в фоновом режиме, и, вероятно, он не является потокобезопасным.

В предположении, что ваш пример является упрощение вашей конкретной проблемы, вы, вероятно, есть некоторое разделение между ViewController и userquery (давайте назовем его findTheObjects Так что в данный момент вы бы что-то вроде:.

myObjectFinder.findTheObjects() 

в этом случае, вы должны пройти в своем собственном блоке завершения, вдоль линий:

myObjectFinder.findTheObjects(completion: { 
    (username, imageThumbnail?) -> Void in 
    dispatch_async(dispatch_get_main_queue(), { 
     // do something with the results like... 
     Model.sharedInstance.friendsPictureModel.addItem(username,FriendImageThumbnail:theResults.imageThumbnail!) 
     self.collectionview.reloadData() 
    }) 
} 

этого блока завершающего затем будет вызывать из вашей секции C.