robertmryan/NetworkManager

Crash when cancel operation.

Closed this issue · 1 comments

Hi Rob, I added button in cell to abort download here is the button action method.
When I click the stop download button then I can able to cancel operation but it crashes when I stop multiple operation by clicking button. Also xcode prints the below error message -

*** NetworkDownloadTaskOperation 0x7fab88411590 went isFinished=YES without being started by the queue it is in

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"NetworkRequestProgressCell";
    NetworkRequestProgressCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    Request *request = self.requests[indexPath.row];
    cell.networkRequestLabel.text = [request.url lastPathComponent];
    [cell.progressView setProgress:request.progress];
    cell.actionButton.tag = indexPath.row;
    [cell.actionButton addTarget:self action:@selector(stopDownload:) forControlEvents:UIControlEventTouchUpInside];
    return cell;
}

- (void)stopDownload:(id)sender {
    UIButton *button = (UIButton *)sender;
    Request *request = self.requests[button.tag];

    for (NSOperation *operaton in self.networkManager.networkQueue.operations) {

        NetworkDataTaskOperation *op = (NetworkDataTaskOperation*)operaton;
        if ([op.task.originalRequest.URL isEqual:request.url]) {
            NSLog(@"Cancel originalRequest.URL = %@",op.task.originalRequest.URL);
            [operaton cancel];

            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:button.tag inSection:0];
            request.progress = 0.0;
            NetworkRequestProgressCell *cell = (id)[self.tableView cellForRowAtIndexPath:indexPath];
            [cell.progressView setProgress:request.progress];
        }
    }
}

Hi Rob,

I did some changes in "NetworkTaskOperation.m" and everything is working fine now.
Below are some changes -

  1. added operationStarted BOOL.

    @property (nonatomic, assign, getter = isOperationStarted) BOOL operationStarted;
  2. Made changes in below 3 methods,

    - (void)start {
        [self setOperationStarted:YES];
        if ([self isCancelled]) {
            self.finished = YES;
            return;
        }
        self.executing = YES;
        [self.task resume];
    }
    
    - (void)cancel {
        [self.task cancel];
        [super cancel];
        [self completeOperation];
    }
    
    - (void)completeOperation {
        if (![self isOperationStarted]) {
            return;
        }
    
        [self willChangeValueForKey:@"isExecuting"];
        self.executing = NO;
        [self didChangeValueForKey:@"isExecuting"];
    
        [self willChangeValueForKey:@"isFinished"];
        self.finished = YES;
        [self didChangeValueForKey:@"isFinished"];
    }