最后我想出了一个稍微开箱即用的解决方案。它是一个用资源计数器信号量扩展的 NSObject 子类。此操作仅在信号量达到零时执行。
SemaphoreDependencyOperation.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
和用法:
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];