用于同步多部分异步调用的模式

时间:2015-08-10 20:31:31

标签: ios objective-c asynchronous

我试图找到在同步多部分异步操作时使用的模式。假设操作系统提供可以启动/停止的服务。请看以下示例:

  1. 开始调用。让守护进程开始。
  2. 守护程序成功响应。做一些其他操作,例如设置必要的操作状态。
  3. 守护进程响应,我们完成了。
  4. 我想要的是防止活动重叠。假设当1.正在处理停止请求(或另一个开始)时发出。该请求必须保持到3.完成。

    我知道dispatches queues并且我实际上正在使用它们,但它们会阻止每个步骤重叠,而不是整个操作。我尝试使用锁,但是我从iOS获得了一个即时日志,告诉我发生了死锁(我不会释放锁直到3.完成)。我也尝试了一些临时方法,但它们一直难以使用。我的最后一次尝试:

    @interface HYPAtomizer : NSObject
    
    // Indicates that the operation is running. A start request was successful    
    @property (readonly) BOOL isRunning;
    
    // Whether the operation/daemon should be running
    @property (readonly) BOOL isRunningRequested;
    
    // Whether we are currently processing a request
    @property (readonly) BOOL isProcessing;
    
    // Whether an error occurred
    @property (readonly) NSError * error;
    
    - (instancetype)init NS_DESIGNATED_INITIALIZER;
    + (instancetype)atomizer;
    
    // These methods return YES if I should proceed with the request, meaning that it's not overlapping
    - (BOOL)startIfPossible;
    - (BOOL)stopIfPossible;
    
    // Call these by the time a request finishes. They will say whether to revert the process, meaning that a request happened during processing that requires the state to turn back (such as a stop request being issued during a start process)
    - (BOOL)revertStartIfNeeded:(NSError *)error;
    - (BOOL)revertStopIfNeeded:(NSError *)error;
    
    // A spontaneous stoppage occurred, such as the daemon stopping by itself
    - (void)notifyStoppage:(NSError *)error;
    
    @end
    

    然后我在关键点调用这些方法,但事实证明很难找到这些关键点。有标准方法吗?

    编辑以便澄清:

    任何特定活动的步骤都不重复,但它们也不是强制性的。因此,启动操作可以执行1,2和3,但如果该步骤检测到错误并且3从未执行,则它也可以在2处停止。步骤不重复,因此1,2,2,2,3,3是不可能的。这些情况是可能的:

    [lock] 1, 2 - fail [unlock]
    [lock] 1, 2, 3 - success [unlock]
    

    如果同时(我等待守护进程)任何其他操作是尝试,无论是开始还是停止,它都不应该执行,而是更新一个标志,指示当前状态应该是什么。可以说(start)是一个开始请求而(stop)是相反的活动。将发生以下情况:

    (start) [lock] 1, 2, 3 [unlocked] (stop) [lock] 1, 2 [unlock]
    (start) [lock] 1, 2, (stop), 3 [unlock] [lock] 1, 2 [unlock]
    

    上一个示例中的(stop)请求是由外部源调用的,它不是启动过程的一部分。正如您在开始结束时所看到的那样,我希望它停止,因为它同时被请求了。最后,如果更多的动作重叠:

    (start) [lock] 1, (stop), 2, (start), 3 [unlock] - nothing happens
    

    在这种情况下,没有任何事情发生,因为在流程结束时,它已经处于上次请求的状态(开始)。

    编辑:BTW,我只是想实现一个像所描述的简单的锁机制。

3 个答案:

答案 0 :(得分:0)

Promises模式是为这种情况设计的。我发现PromiseKit是iOS上的一个很好的实现。链接是您正在寻找的功能。

PromiseKit

Chaining

答案 1 :(得分:0)

你听说过NSOperationQueue课吗?我猜这正是你要找的东西。您可以非常轻松地定义优先级,依赖关系,取消单个操作等。漂亮而整洁的API。只需查看文档(抱歉没有发布直接链接)。

答案 2 :(得分:0)

您可以为您的NSOperations设置completionBlock(),您可以将其与经理类中的单身属性一起使用,以检查您的状态等。

设置startOperation,对于startOperation.completionBlock,设置类似startOperation.completionBlock = ^ {[[DaemonManager defaultManager] checkIfStopRequestedAndHandle];};。

使用completionBlock,addDependency和isCancelled以及isFinished,您应该有足够的工具来根据需要定制执行步骤/依赖项