Ivan Rysev
Ivan Rysev

Reputation: 61

AFNetworking 2: canceling batch requests

I'm using AFNetworking2 code for batching requests. I have copy & paste from example code and have changed upload operation to download. I need to cancel download operations on controllers disappearing. I'm trying to implement cancellation:

    [[self.imagesQueue.operations 
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) 
{ return [evaluatedObject isKindOfClass:[AFHTTPRequestOperation class]]; }]] makeObjectsPerformSelector:@selector(cancel)];

of batch request (download images):

-(void) startDownloadImages {

    NSMutableArray *mutableOperations = [NSMutableArray array];
    //self.downloadOperations = [NSMutableArray array];
    for (NSString *str in _project.frames) {

        NSURLRequest *request =
        [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET"
                                                      URLString:str
                                                     parameters:nil];

        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

         NSLog(@"OK %@", str);


        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"FAILS %@", str);
        }];

        [mutableOperations addObject:operation];
    }

    NSArray *operations =
    [AFURLConnectionOperation batchOfRequestOperations:mutableOperations
                                         progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
        NSLog(@"%lu of %lu complete", (unsigned long)numberOfFinishedOperations, (unsigned long)totalNumberOfOperations);
    } completionBlock:^(NSArray *operations) {
        NSLog(@"All operations in batch complete");

    }];

    self.imagesQueue = [[NSOperationQueue alloc] init];
    self.imagesQueue.name = @"com.imagesqueue";
    self.imagesQueue.maxConcurrentOperationCount = 1;

    [self.imagesQueue addOperations:operations waitUntilFinished:NO];
    //[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];
}

Series of starts and cancellations leads to EXC_BREAKPOINT (code=EXC_ARM_BREAKPOINT, subcode=0xdefe):

libdispatch.dylib`dispatch_group_leave:
    0x37e1e7d8:  dmb    ishst
    0x37e1e7dc:  ldrex  r1, [r0, #40]
    0x37e1e7e0:  adds   r1, #1
    0x37e1e7e2:  strex  r2, r1, [r0, #40]
    0x37e1e7e6:  cmp    r2, #0
    0x37e1e7e8:  bne    0x37e1e7dc                ; dispatch_group_leave + 4
    0x37e1e7ea:  cmp.w  r1, #4294967295
    0x37e1e7ee:  ble    0x37e1e7fe                ; dispatch_group_leave + 38
    0x37e1e7f0:  mvn    r2, #2147483648
    0x37e1e7f4:  cmp    r1, r2
    0x37e1e7f6:  it     eq
    0x37e1e7f8:  beq.w  0x37e21df8                ; _dispatch_group_wake
    0x37e1e7fc:  bx     lr
    0x37e1e7fe:  trap   
    0x37e1e800:  nop    
    0x37e1e802:  nop 

Any tips?

Upvotes: 4

Views: 541

Answers (1)

javierfdezg
javierfdezg

Reputation: 2107

Try declaring str as a block variable (you are accessing it in a block):

__block NSString *str;

for (str in _project.frames) {

You can also try to check if the operation has been completed before performing the cancel selector.

In the view will dissappear method you could invoke the cancelAllOperations on your image queue to cancel all the remaining operations.

Upvotes: 1

Related Questions