2014-08-29 11 views
2

Я использую Alamofire (AF) в параллельной операционной очереди для запуска сетевых команд в моем проекте. Иногда завершение AFHandler не срабатывает, оставляя мой NSOperation висящим (ожидая сообщения о завершении, которое он никогда не получит).Очереди Alamofire и параллельной работы

Например. Я не буду видеть «ответ» журнал, но не соответствующие «видеть меня» войти в dispatch_async АФ ниже:

public func response(priority: Int = DISPATCH_QUEUE_PRIORITY_DEFAULT, queue: dispatch_queue_t? = nil, serializer: (NSURLRequest, NSHTTPURLResponse?, NSData?, NSError?) -> (AnyObject?, NSError?), completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self { 
NSLog("markse-response") 

    dispatch_async(self.delegate.queue, { 
NSLog("markse-see me") 
     dispatch_async(dispatch_get_global_queue(priority, 0), { 
      if var error = self.delegate.error { 
       dispatch_async(queue ?? dispatch_get_main_queue(), { 
        completionHandler(self.request, self.response, nil, error) 
       }) 
      } else { 
       let (responseObject: AnyObject?, serializationError: NSError?) = serializer(self.request, self.response, self.delegate.data, nil) 

       dispatch_async(queue ?? dispatch_get_main_queue(), { 
        completionHandler(self.request, self.response, responseObject, serializationError) 
       }) 
      } 
     }) 
    }) 

    return self 
} 

Это мой NSOperation (AsynchronousCommand является NSOperation подкласс):

import Alamofire 

class SettingsListCommand: AsynchronousCommand { 

    override func execute() { 
     if cancelled { return } 

     let endpoint = "https://api.github.com/users/cog404/orgs" 

     DLogVerbose("AF request") 
     weak var weakSelf = self 
     Alamofire.request(.GET, 
      endpoint, 
      parameters:nil) 
      .responseJSON {(request, response, JSON, error) in 
       DLogVerbose("AF response") 
       if let strongSelf = weakSelf { 
        if strongSelf.cancelled { 
         strongSelf.finish() 
         return 
        } 
        DLogVerbose(JSON) 
        strongSelf.finish() 
       } 
     } 
    } 

} 

Это происходит только «случайно», что очень затрудняет отладку.

Кто-нибудь, кто хорошо разбирается в резьбе, знает, что может быть неправильным?

Любой совет очень ценится. Проект, который поможет проиллюстрировать проблему, - here.

ответ

3

Очередь отправки делегата запроса является последовательной, что означает, что она будет обрабатывать только один блок за раз, в порядке отправки блоков (FIFO). Если второй оператор журнала не срабатывает, это связано с тем, что предыдущий блок еще не завершился.

+2

Мои 2 цента: это решение кажется слишком сложным. Если вам нужно _ NSOperation, просто используйте операцию с блоком и 'dispatch_semaphore'. – mattt

+2

Спасибо, матовый. Мне потребовалось некоторое время, чтобы прочитать GCD, но это поведение имеет смысл сейчас. Я рассмотрю метод dispatch_semaphore после большего чтения (я долгое время жил в мире NSOperation). –