Objective-C的,可能要排队异步NSURLRequests? [英] objective-c, possible to queue async NSURLRequests?

查看:140
本文介绍了Objective-C的,可能要排队异步NSURLRequests?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到这问题听起来是矛盾的。我有几个异步请求的应用程序中走出去。的情况是,第一个异步请求是认证请求,而其余的将使用由成功的认证请求返回一个访问令牌。

这两个明显的解决办法是:


  1. 运行他们所有的同步和风险UI模块。 (坏的选择)

  2. 异步运行它们,并把请求2-N在完成处理程序的第一个。 (不实用)

麻烦的是,随后的请求可以在任何地方项目的处理,在任何时候。失败的情况是,如果第二个请求是在第一个身份验证请求发出后,立即调用,并返回访问令牌之前。

我的问题因而,有没有什么办法来排队异步请求,或以某种方式说,不发给他们,直到第一个请求成功返回?

编辑:

为什么?(2)是不实际的:首先是认证请求,应用程序加载时发生。第2 +,可能会出现马上,在这种情况下,它是实际的,但它也可能在一个完全独立的类或大型应用程序的任何其他部分发生。我不能把本质在完成处理整个应用程序。其他访问的API请求可能发生在其他类,在任何时候。即使是1-2天远后发生的许多其他的事情。

解决方案:

使用身份验证的呼叫信号锁定阻止其他所有调用直到接收到它

  //伪code//在AUTH开始
_semaphore = dispatch_semaphore_create(0)//在API调用的开始
如果(_accessToken ==零和放大器;&安培; [_ apiCall isEqualToString:@AUTH]!){
    dispatch_semaphore_wait(_semaphore,DISPATCH_TIME_FOREVER);
}//在与身份验证令牌身份验证结束
dispatch_semaphore_signal([[SFApi实例]旗语]);
_accessToken = ...;


解决方案

在类似案例,我总是发现最简单的方法来写code同步,并得到它在UI线程上运行的第一,正确,只是为了调试。然后,移动操作独立的线程,并确保您处理并发。

在这种情况下,并发了完善的机制是的信号灯的;当它完成,和所有其他的操作都阻止在其上的认证操作清除信号。一旦认证完成,水闸被打开。

相关职能从中央调度文档dispatch_semaphore_create()和dispatch_semaphore_wait():<一href=\"https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/doc/uid/TP40008079-CH2-SW2\" rel=\"nofollow\">https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/doc/uid/TP40008079-CH2-SW2

另一个出色的解决方案是创建一个队列用的屏障的:

一个调度屏障允许你创建一个并发调度队列内的同步点。当它遇到一个障碍,并发队列延迟障碍块,直到完成屏障执行前提交所有块的执行(或任何其它块)。在这一点上,阻挡块由本身执行。完成后,队列恢复正常执行行为。

看起来像你说对了一个信号运行,很好地完成!

I realize this question sounds contradictory. I have several Async requests going out in an application. The situation is that the first async request is an authentication request, and the rest will use an access token returned by the successful authentication request.

The two obvious solutions would be:

  1. run them all synchronous, and risk UI block. (bad choice)
  2. run them async, and put request 2-N in the completion handler for the first one. (not practical)

The trouble is that the subsequent requests may be handled anywhere in the project, at anytime. The failure case would be if the 2nd request was called immediately after the 1st authentication request was issued, and before the access token was returned.

My question thus is, is there any way to queue up Async requests, or somehow say not to issue them until the first request returns successfully?

EDIT:

Why (2) is not practical: The first is an authentication request, happening when the app loads. The 2nd+ may occur right away, in which case it is practical, but it also may occur in a completely separate class or any other part of a large application. I can't essentially put the entire application in the completion handler. Other accesses to the API requests may occur in other classes, and at anytime. Even 1-2 days away after many other things have occurred.

SOLUTION:

//pseudo code using semaphore lock on authentication call to block all other calls until it is received

// at start of auth
_semaphore = dispatch_semaphore_create(0)

// at start of api calls
if(_accessToken == nil && ![_apiCall isEqualToString:@"auth]){
    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
}

// at end of auth with auth token
dispatch_semaphore_signal([[SFApi Instance] semaphore]);
_accessToken = ...;

解决方案

In cases like this I always find it easiest to write the code synchronously and get it running on the UI thread first, correctly, just for debugging. Then, move the operations to separate threads and make sure you handle concurrency.

In this case the perfect mechanism for concurrency is a semaphore; the authentication operation clears the semaphore when it is done, and all the other operations are blocking on it. Once authentication is done, floodgates are open.

The relevant functions are dispatch_semaphore_create() and dispatch_semaphore_wait() from the Grand Central Dispatch documentation: https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/doc/uid/TP40008079-CH2-SW2

Another excellent solution is to create a queue with a barrier:

A dispatch barrier allows you to create a synchronization point within a concurrent dispatch queue. When it encounters a barrier, a concurrent queue delays the execution of the barrier block (or any further blocks) until all blocks submitted before the barrier finish executing. At that point, the barrier block executes by itself. Upon completion, the queue resumes its normal execution behavior.

Looks like you got it running with a semaphore, nicely done!

这篇关于Objective-C的,可能要排队异步NSURLRequests?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆