Ios 与RestKit操作会合

Ios 与RestKit操作会合,ios,restkit,grand-central-dispatch,nsoperation,Ios,Restkit,Grand Central Dispatch,Nsoperation,我正试图建立一个相当复杂的RestKit操作链。首先,我必须向父对象列表发出请求(我们称之为parentRequestOperation),对于列表中的每个父对象,我必须创建另一个请求操作来获取相关对象(我们称之为childRequestOperation)。显然,我只能在parentRequestOperation的success()块中创建childRequestOperations,因为我以前不知道应该创建多少以及使用哪些详细信息 我想在所有操作完成后得到一些反馈。为此,我使用我的处理块(

我正试图建立一个相当复杂的RestKit操作链。首先,我必须向父对象列表发出请求(我们称之为parentRequestOperation),对于列表中的每个父对象,我必须创建另一个请求操作来获取相关对象(我们称之为childRequestOperation)。显然,我只能在parentRequestOperation的success()块中创建childRequestOperations,因为我以前不知道应该创建多少以及使用哪些详细信息

我想在所有操作完成后得到一些反馈。为此,我使用我的处理块(我们称之为finishedOperation)创建了一个NSOperation实例,向其添加了对parentRequest的依赖项,并将其添加到RKObjectManager的operationQueue中

我的问题是如何在childRequestOperations和FinishedOperations之间进行“会合”。在创建childRequestOperation之后,我尝试将对childRequestOperation的依赖添加到finishedOperation(仍在parentRequestOperation的成功块中)。但问题是RestKit在与RKObjectManager的operationQueue不同的调度队列中异步调用success块,因此一旦parentRequestOperation完成,finishedOperation将在我可以添加对childRequestOperation的新依赖项之前被触发


在类似场景中设置finishedOperation的最佳实践是什么?

您可以查看设置要使用的操作的
successCallbackQueue
,并在执行现有相关操作时将自己的任务推到同一队列上。如果您使用的队列是串行的,那么您可以保证执行顺序。

最后,我提出了一个稍微开箱即用的解决方案。它是一个NSObject子类,使用资源计数器信号量进行扩展。此操作仅在信号量达到零时执行

信号量依赖操作.h

@interface SemaphoreDependencyOperation : NSOperation

@property (atomic, readonly) int32_t dependencySemaphore;

-(void)incrementDependencySemaphore;
-(void)decrementDependencySemaphore;

@end
信号量依赖操作.m

#import "SemaphoreDependencyOperation.h"
#include <libkern/OSAtomic.h>

@implementation SemaphoreDependencyOperation

-(void)incrementDependencySemaphore
{
    [self willChangeValueForKey:@"dependencySemaphore"];
    OSAtomicIncrement32(&_dependencySemaphore);
    [self didChangeValueForKey:@"dependencySemaphore"];
}

-(void)decrementDependencySemaphore
{
    [self willChangeValueForKey:@"dependencySemaphore"];
    OSAtomicDecrement32(&_dependencySemaphore);
    [self didChangeValueForKey:@"dependencySemaphore"];
}

+(NSSet *)keyPathsForValuesAffectingIsReady
{
    return [NSSet setWithObject:@"dependencySemaphore"];
}

-(BOOL)isReady
{
    return [super isReady] && _dependencySemaphore <= 0;
}

@end

谢谢你的回复。我看过successCallbackQueue,但不幸的是,它不是NSOperationQueue,而是dispatch______________________________________________________(但是您可以从您的操作中将这些块添加到队列中…)问题在于RestKit异步调用successBlock(在RKObjectRequestOperation.m:
dispatch\u async(self.successCallbackQueue?:dispatch\u get\u main\u queue(),^{success(self,self.mappingResult);})
)因此,无论我在successBlock中尝试执行什么操作,都会在RKObjectRequestOperation完成后发生。
dispatch_async
只是将块添加到队列并返回,重要的是将块添加到队列的顺序。感谢您的解释。不幸的是,只有在成功执行RKObjectRequest操作时,我才能将新块添加到队列中ock正在有效执行,因为我之前没有创建新块所需的必要信息。新块怎么可能先于successBlock?
SemaphoreDependencyOperation* trackerOperation = [[UpdateTrackerOperation alloc] init];
[trackerOperation setCompletionBlock:^{
    NSLog(@"Everything done"); 
}];

NSURLRequest* parentRequest = // ...
RKObjectRequestOperation* parentRequestOperation =
  [self.objectManager objectRequestOperationWithRequest:parentRequest
                                                success:
  ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
  {
    // create childRequestOperations based on mappingResult
    for (MyObject* myObject in [mappingResult array]) 
    {
       NSURLRequest* childRequest = // ... create it from myObject
       RKObjectRequestOperation* childRequestOperation = 
         [self.objectManager objectRequestOperationWithRequest:parentRequest
                                                       success:
         ^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
         {
           // ...
           [trackerOperation decrementDependencySemaphore];
         }
                                                       failure:nil];

         [self.objectManager enqueueObjectRequestOperation:childRequestOperation];
         [trackerOperation incrementDependencySemaphore];
    }
    [trackerOperation decrementDependencySemaphore];
  }
                                                failure:nil];

[self.objectManager enqueueObjectRequestOperation:parentRequestOperation];
[trackerOperation incrementDependencySemaphore];
[self.objectManager.operationQueue addOperation:trackerOperation];