기내 API 호출 수를 2로 제한하고 싶습니다. NSOperationQueue
을 생성하고 블록을 대기열에 추가 할 수 있지만 각 API 호출에는 완료 블록이 있으므로 초기 호출은 제한적이지만 완료 블록의 실행을 기반으로 큐의 처리를 제한하는 방법을 알지 못합니다.iOS에서 NSBlockOperation을 사용하여 비동기 API 호출을 조절 함
아래 코드에서 아무 때 나 2 회 이상 호출 API를 사용할 수 있습니다.
NSOperationQueue *requestQueue = [[NSOperationQueue alloc] init];
service.requestQueue.maxConcurrentOperationCount = 2;
for (int i = 0; i < 100; i++)
{
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[self invokeAPI:kAPIName completion:^BOOL(APIResult *result) {
// Do stuff
}
[requestQueue addOperation:operation];
}
}
정확한 패턴을 가리키는 포인터가 있으면 좋겠다.
편집 - 마크 - 알렉산더의 답변을 바탕으로
이 클래스는 dataAccessService에서 생성 및 주입됩니다 주어진보기의 메모리 관점에서 안전한 방법이며, 작업을 캡슐화하는이 클래스를 만들었습니다 완성 된 블록은 자체에 대한 참조를 가지고 있으며 완료 블록이 실행되는 보다 앞에이라는 마무리가 필요합니까?
@interface MAGApiOperation : NSOperation
@property (nonatomic, strong) id<MAGDataAccessServiceProtocol> dataAccessService;
@property (nonatomic, copy) NSString *apiName;
@property (nonatomic, copy) BOOL (^onCompletion)(APIResult *);
+ (instancetype)apiOperationWithName:(NSString *)apiName dataAccessService:(id<MAGDataAccessServiceProtocol>)dataAccessService completion:(BOOL (^)(APIResult *))onCompletion;
@implementation MAGApiOperation
@synthesize executing = _isExecuting;
@synthesize finished = _isFinished;
#pragma mark - Class methods
/// Creates a new instance of MAGApiOperation
+ (instancetype)apiOperationWithName:(NSString *)apiName dataAccessService:(id<MAGDataAccessServiceProtocol>)dataAccessService completion:(BOOL (^)(APIResult *))onCompletion {
MAGApiOperation *operation = [[self alloc] init];
operation.apiName = apiName;
operation.dataAccessService = dataAccessService;
operation.onCompletion = onCompletion;
return operation;
}
#pragma mark - NSOperation method overrides
- (void)start {
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
if (!self.isCancelled)
{
[self invokeApiWithName:self.apiName completion:self.onCompletion];
}
}
- (void)finish {
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
#pragma mark - Private methods
/// Invokes the api with the name then executes the completion block
- (void)invokeApiWithName:(NSString *)apiName completion:(BOOL (^)(VAAInvokeAPIResult *))onCompletion {
[self.dataAccessService invokeAPI:kAPIName completion:^BOOL(APIResult *result) { {
[self finish];
return onCompletion(result);
}];
}
을 (아래 참조 willChange 및 didChange 통화가 정말 중요주의) 자신의 작업을 표시, 그것은 필요가 없습니다 언제든지 2 개 이상의 API 호출을 병렬로 수행 할 수 있습니다. –
NSOperation에는 이미 사용할 수있는 completionBlock이 있습니다. 당신은 당신 자신의 것을 구현할 필요가 없다. 대신 결과를'@ property'에 저장 한 다음 작업을 호출 할 때 myOperation.completionBlock =^{/ * myOperation.results * /}에 액세스 할 수 있습니다. 말이된다? –