objective-ciosnsoperationqueuensinvocationoperation

UI didn't update because of NSOperationQueue waitUntilFinished YES


I got an issue. The scenario is like this: I got an NSOperationQueue that contain various NSOperationQueue that need to waitUntilDone:YES. And I need to update the UI too as the queue or the operation is running. What is the best way to handle this situation?

I have tried performSelectorOnMainThread, but is it necessary to use this method every time I need to update the UI. It is seems not a good solution.

- (void)loadPreviewPageWithMagazineID:(NSString *)magazineID userID:(NSString *)userID {
NSMutableArray *operationArray = [NSMutableArray array];
for (NSInteger i = 1; i <= _numTotalPages; ++i) {
    //NSLog(@"currenpage = %d, index = %d",_selectedPage,pageIndex);
    NSDictionary *arguments = [NSDictionary dictionaryWithObjectsAndKeys:magazineID, 
                               @"itemID", userID, @"userID", [NSNumber numberWithInt:i],
                               @"pageNumber", nil];
    AFOperation *imageOperation = 
        [[AFOperation alloc] initWithTarget:self 
                                   selector:@selector(savePageToDisk:) 
                                     object:arguments];
    [imageOperation addObserver:self forKeyPath:@"isFinished" options:0 context:nil];
    [imageOperation setUserInfo:arguments];
    [operationArray addObject:imageOperation];
    [imageOperation release];
}
[_imageQueue addOperations:operationArray waitUntilFinished:YES];
}


- (void)processingMagazine:(NSDictionary *)arguments {
// load pdf document from decrypted data 
NSString *userID = [arguments objectForKey:@"userID"];
NSString *magazineID = [arguments objectForKey:@"itemID"];

[self loadPreviewPageWithMagazineID:magazineID userID:userID];
}

So each time to update UI I need to call

[_collectionCoverView performSelectorOnMainThread:@selector(setDownloadProgress:)
                                       withObject:[NSNumber numberWithFloat:progress] 
                                    waitUntilDone:YES];

Is there any appropriate way to handle the UI?

Solution

  • I didn understand much from your code. But to accomplish what you want, you can add the UI update code at the end of your AFOperation method. I mean to say, UI will be updated automatically once some processing is done, if you add it in the operation method.

    Also generally UI update happens in MainThread. SO there is nothing wrong in calling performSelectorInMainThread.