mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 22:51:50 +08:00
Adjust completion block implementation for RKPaginator to enable completion block to be invoked when used without a strong reference. fixes #1119 fixes #1093
This commit is contained in:
@@ -201,6 +201,20 @@ static NSString *RKStringDescribingURLResponseWithData(NSURLResponse *response,
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setWillMapDeserializedResponseBlock:(id (^)(id))block
|
||||
{
|
||||
if (!block) {
|
||||
_willMapDeserializedResponseBlock = nil;
|
||||
} else {
|
||||
__unsafe_unretained id weakSelf = self;
|
||||
_willMapDeserializedResponseBlock = ^id (id deserializedResponse) {
|
||||
id result = block(deserializedResponse);
|
||||
[weakSelf setWillMapDeserializedResponseBlock:nil];
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCompletionBlockWithSuccess:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
|
||||
failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
|
||||
@@ -178,20 +178,21 @@ static NSUInteger RKPaginatorDefaultPerPage = 25;
|
||||
|
||||
// Add KVO to ensure notification of loaded state prior to execution of completion block
|
||||
[self.objectRequestOperation addObserver:self forKeyPath:@"isFinished" options:0 context:nil];
|
||||
|
||||
__weak RKPaginator *weakSelf = self;
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-retain-cycles"
|
||||
[self.objectRequestOperation setWillMapDeserializedResponseBlock:^id(id deserializedResponseBody) {
|
||||
NSError *error = nil;
|
||||
RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:deserializedResponseBody destinationObject:weakSelf mapping:weakSelf.paginationMapping];
|
||||
RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:deserializedResponseBody destinationObject:self mapping:self.paginationMapping];
|
||||
BOOL success = [mappingOperation performMapping:&error];
|
||||
if (!success) {
|
||||
weakSelf.pageCount = 0;
|
||||
weakSelf.currentPage = 0;
|
||||
self.pageCount = 0;
|
||||
self.currentPage = 0;
|
||||
RKLogError(@"Paginator didn't map info to compute page count. Assuming no pages.");
|
||||
} else if (weakSelf.perPage && [weakSelf hasObjectCount]) {
|
||||
float objectCountFloat = weakSelf.objectCount;
|
||||
weakSelf.pageCount = ceilf(objectCountFloat / weakSelf.perPage);
|
||||
RKLogInfo(@"Paginator objectCount: %ld pageCount: %ld", (long)weakSelf.objectCount, (long)weakSelf.pageCount);
|
||||
} else if (self.perPage && [self hasObjectCount]) {
|
||||
float objectCountFloat = self.objectCount;
|
||||
self.pageCount = ceilf(objectCountFloat / self.perPage);
|
||||
RKLogInfo(@"Paginator objectCount: %ld pageCount: %ld", (long)self.objectCount, (long)self.pageCount);
|
||||
} else {
|
||||
RKLogError(@"Paginator perPage set is 0.");
|
||||
}
|
||||
@@ -199,14 +200,15 @@ static NSUInteger RKPaginatorDefaultPerPage = 25;
|
||||
return deserializedResponseBody;
|
||||
}];
|
||||
[self.objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
|
||||
if (weakSelf.successBlock) {
|
||||
weakSelf.successBlock(weakSelf, [mappingResult array], weakSelf.currentPage);
|
||||
if (self.successBlock) {
|
||||
self.successBlock(self, [mappingResult array], self.currentPage);
|
||||
}
|
||||
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
|
||||
if (weakSelf.failureBlock) {
|
||||
weakSelf.failureBlock(weakSelf, error);
|
||||
if (self.failureBlock) {
|
||||
self.failureBlock(self, error);
|
||||
}
|
||||
}];
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
if (self.operationQueue) {
|
||||
[self.operationQueue addOperation:self.objectRequestOperation];
|
||||
|
||||
@@ -220,9 +220,7 @@ static NSString * const RKPaginatorTestResourcePathPattern = @"/paginate?per_pag
|
||||
} failure:nil];
|
||||
[paginator loadPage:1];
|
||||
[paginator waitUntilFinished];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
expect(blockObjects).notTo.beNil();
|
||||
});
|
||||
expect(blockObjects).willNot.beNil();
|
||||
}
|
||||
|
||||
- (void)testOnDidFailWithErrorBlockIsInvokedOnError
|
||||
@@ -235,9 +233,19 @@ static NSString * const RKPaginatorTestResourcePathPattern = @"/paginate?per_pag
|
||||
}];
|
||||
[paginator loadPage:999];
|
||||
[paginator waitUntilFinished];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
expect(expectedError).notTo.beNil();
|
||||
});
|
||||
expect(expectedError).willNot.beNil();
|
||||
}
|
||||
|
||||
- (void)testInvocationOfCompletionBlockWithoutWaiting
|
||||
{
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:self.paginationURL];
|
||||
RKPaginator *paginator = [[RKPaginator alloc] initWithRequest:request paginationMapping:self.paginationMapping responseDescriptors:@[ self.responseDescriptor ]];
|
||||
__block NSArray *blockObjects = nil;
|
||||
[paginator setCompletionBlockWithSuccess:^(RKPaginator *paginator, NSArray *objects, NSUInteger page) {
|
||||
blockObjects = objects;
|
||||
} failure:nil];
|
||||
[paginator loadPage:1];
|
||||
expect(blockObjects).willNot.beNil();
|
||||
}
|
||||
|
||||
- (void)testLoadingNextPageOfObjects
|
||||
|
||||
Reference in New Issue
Block a user