2

プロジェクトでネットワーク コマンドを実行するために、同時操作キューでAlamofire (AF)を使用しています。AF の completionHandler が起動せず、NSOperation がハングしたままになることがあります (決して受信しない終了メッセージを待機しています)。

例えば。「応答」ログは表示されますが、以下の AF の 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()
                }
        }
    }

}

これは「時折」しか発生しないため、デバッグが非常に困難です。

スレッドをよく理解している人は、何がうまくいかないのか知っていますか?

アドバイスをいただければ幸いです。問題を説明するのに役立つプロジェクトがここにあります。

4

1 に答える 1

3

リクエスト デリゲートのディスパッチ キューはシリアルです。つまり、ブロックがディスパッチされた順番 (FIFO) で、一度に 1 つのブロックのみを処理します。2 番目のログ ステートメントが実行されない場合は、前のブロックがまだ終了していないことが原因です。

于 2014-09-24T23:30:40.233 に答える