我正在尝试使用多个串行队列连续运行一些密集型进程。代码正在运行,但即使调用该方法,我的UI更新也不会发生。
以下是以串行方式运行多个进程的代码。
- (void)importProcess {
dispatch_queue_t serialQueue = dispatch_queue_create("com.cyt.importprocessqueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"checking image sizes");
__block NSMutableArray *assets;
dispatch_sync(serialQueue, ^() {
assets = [self checkImageSizes];
});
dispatch_sync(serialQueue, ^() {
[self appendLogToTextView:[NSString stringWithFormat:@"%i screenshot(s) ignored due to invalid size.",(int)(self.assets.count-assets.count)]];
if(assets.count==0) {
[self showNoRunesFoundAlert];
}
else {
[self appendLogToTextView:@"Preparing to process screenshots..."];
self.assets = [NSArray arrayWithArray:assets];
}
});
NSLog(@"processing uploads");
dispatch_sync(serialQueue, ^() {
[self processUploads];
});
NSLog(@"recognizing images");
dispatch_sync(serialQueue, ^() {
[self recognizeImages];
});
NSLog(@"recognizing images");
dispatch_sync(serialQueue, ^() {
[self processRuneText];
});
//dispatch_sync(dispatch_get_main_queue(), ^ {
//});
}
在checkImageSizes
内,我有另一个串行队列:
- (NSMutableArray *)checkImageSizes {
dispatch_queue_t serialQueue = dispatch_queue_create("com.cyt.checkimagesizequeue", DISPATCH_QUEUE_SERIAL);
NSMutableArray *assets = [NSMutableArray new];
for(int i=0;i<self.assets.count;i++) {
dispatch_sync(serialQueue, ^{
PHAsset *asset = (PHAsset *)self.assets[i];
if(asset.pixelWidth==self.screenSize.width && asset.pixelHeight==self.screenSize.height) {
[assets addObject:asset];
NSString *logText = [NSString stringWithFormat:@"Screenshot %i/%i size is OK.",i+1,(int)self.assets.count];
[self performSelectorOnMainThread:@selector(appendLogToTextView:) withObject:logText waitUntilDone:YES];
}
else {
[self appendLogToTextView:[NSString stringWithFormat:@"ERROR: Screenshot %i/%i has invalid size. Skipping...",i+1,(int)self.assets.count]];
}
});
}
return assets;
}
appendLogToTextView
方法应该更新UI。这是代码:
- (void)appendLogToTextView:(NSString *)newText {
dispatch_block_t block = ^ {
self.logText = [NSString stringWithFormat:@"%@\n%@", self.logText, newText];
NSString *textViewText = [self.logText substringFromIndex:1];
[UIView setAnimationsEnabled:NO];
if(IOS9) {
[self.textView scrollRangeToVisible:NSMakeRange(0,[self.textView.text length])];
self.textView.scrollEnabled = NO;
self.textView.text = textViewText;
self.textView.scrollEnabled = YES;
}
else {
self.textView.text = textViewText;
NSRange range = NSMakeRange(self.textView.text.length - 1, 1);
[self.textView scrollRangeToVisible:range];
}
[UIView setAnimationsEnabled:YES];
};
if ([NSThread isMainThread]) {
block();
}
else {
dispatch_sync(dispatch_get_main_queue(), block);
}
}
正如您所看到的,我尝试直接调用appendLogToTextView
并使用performSelectorOnMainThread
。但是,即使我确认正确调用了该方法,我也没有对文本视图进行任何更新。
有趣的是,当我只使用单个串行队列并使用迭代计数来调用下一个方法时,UI更新正常工作,如下面的代码所示(_serialQueue在viewDidLoad
中定义)。但是,我不相信实现是好的做法,因为我在串行队列中包装串行队列。
- (void)checkImageSizes {
NSMutableArray *assets = [NSMutableArray new];
for(int i=0;i<self.assets.count;i++) {
dispatch_async(_serialQueue, ^{
PHAsset *asset = (PHAsset *)self.assets[i];
if(asset.pixelWidth==self.screenSize.width && asset.pixelHeight==self.screenSize.height) {
[assets addObject:asset];
[self appendLogToTextView:[NSString stringWithFormat:@"Screenshot %i/%i size is OK.",i+1,(int)self.assets.count]];
}
else {
[self appendLogToTextView:[NSString stringWithFormat:@"ERROR: Screenshot %i/%i has invalid size. Skipping...",i+1,(int)self.assets.count]];
}
//request images
if(i==self.assets.count-1) {
[self appendLogToTextView:[NSString stringWithFormat:@"%i screenshot(s) ignored due to invalid size.",(int)(self.assets.count-assets.count)]];
if(assets.count==0) {
[self showNoRunesFoundAlert];
}
else {
[self appendLogToTextView:@"Preparing to process screenshots..."];
self.assets = [NSArray arrayWithArray:assets];
[self processUploads];
}
}
});
}
}
我不了解导致此版本代码中的UI更新工作的串行队列,但我尝试“更清洁”的实现失败了?
答案 0 :(得分:0)
最后,我最终使用了调度组和完成块来解决这个问题。