简体   繁体   中英

ASINetworkQueue inside NSOperation blocking main thread

I'm using an NSOperation to collect data that should be downloaded (takes 2-5 sec.) and afterwards I download this. I've put a ASINetworkQueue inside this NSOperation to start downloading the previously collected data.

Everything works fine but when I call cancelAllOperations on my ASINetworkQueue , the main thread blocks and the UI Freezes. Why is this happening? Everything else works fine.

Here is my Code:

- (void)main {
    //ManagedObjectContext for operations
    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [[NSManagedObjectContext alloc] init];


    [self.managedObjectContext setPersistentStoreCoordinator: [appDelegate persistentStoreCoordinator]];

    // Register context with the notification center
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc addObserver:self
           selector:@selector(mergeChanges:)
               name:NSManagedObjectContextDidSaveNotification
             object:self.managedObjectContext];


    [self startDownload];


    if (!self.downloadDidFail) {
        [self moveFiles];

        [self.managedObjectContext save:nil];
    }
}

- (void)startDownload {    
    self.downloadQueue = [ASINetworkQueue queue];
    self.downloadQueue.delegate = self;
    [self.downloadQueue setRequestDidFailSelector:@selector(dataRequestFailed:)];
    [self.downloadQueue setRequestDidFinishSelector:@selector(dataRequestFinished:)];
    [self.downloadQueue setQueueDidFinishSelector:@selector(dataQueueFinished:)];
    [self.downloadQueue setShouldCancelAllRequestsOnFailure:YES];
    [self.downloadQueue setDownloadProgressDelegate:self.progressView];

    for (File *dataFile in self.dataFiles) {
            ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:dataFile.url]];
            [request setDownloadDestinationPath:dataFile.path];

            [self.downloadQueue addOperation:request];
        }
    }

    [self.downloadQueue go];
    [self.downloadQueue waitUntilAllOperationsAreFinished];
}

- (void)dataRequestFinished:(ASIHTTPRequest *)request {
    NSLog(@"DL finished");
}

- (void)dataRequestFailed:(ASIHTTPRequest *)request {
    DLog(@"Download failed");

    self.downloadDidFail = YES;
}

- (void)dataQueueFinished:(ASINetworkQueue *)queue {
    DLog(@"Finished Data Queue");
}

- (void)cancelDownload {
    self.canceledDownload = YES;

    [self.downloadQueue cancelAllOperations];
}

I had the same problem and solved by calling:

[queue setShouldCancelAllRequestsOnFailure:NO]

before calling:

[queue cancelAllOperations].

What does your failure delegate method do? ASIHTTPRequest will run that on the main thread by default, so if it does a lot of processing (or there are a lot of requests) this could take quite some time.

ASI requests responses and queue responses are deliberately moved to the main thread for library design purposes. You have two solution: -Subclass ASIHTTPRequest and overwrite 2 methods. (Look for in the code something like "subclass for main thread"). -Modify the library. (Easy, but personally I don't like this solution).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM