- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题:
当在后台延迟加载100个以上的图标列表时,我达到了GCD线程限制(64个线程),这导致我的应用在主线程上冻结并带有semaphore_wait_trap
。我想重组我的线程代码以防止这种情况的发生,同时仍然异步加载图标以防止UI阻塞。
上下文:
我的应用程序在屏幕上加载了SVG图标。金额平均在10-200之间。通过使用本地SVG图像或远程SVG图像(如果具有自定义图标)绘制图标,然后对其进行后处理以获得最终图像结果。
因为这要花一些时间,并且它们对于用户而言并不重要,所以我想在后台加载它们并对其进行后处理,以便它们随着时间的流逝而弹出。对于每个图标,我使用以下内容:
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
//code to be executed in the background
SVGKImage *iconImage = [Settings getIconImage:location];
dispatch_async(dispatch_get_main_queue(), ^{
//code to be executed on the main thread when background task is finished
if (iconImage) {
[iconImgView setImage:iconImage.UIImage];
}
});
});
getIconImage
方法处理基本SVG的初始加载,基本SVG会与
[NSInputStream inputStreamWithFileAtPath:path]
(如果是本地)同步,并与
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&errorWithNSData]
(如果应远程加载)同步读取。这一切都是同步发生的。
UIImageView
之前,需要对SVG进行重新着色的一些后期处理。
_iconOperationQueue = [[NSOperationQueue alloc]init];
_iconOperationQueue.maxConcurrentOperationCount = 8;
// Code will be executed on the background
[_iconOperationQueue addOperationWithBlock:^{
// I/O code
SVGKImage *baseIcon = [Settings getIconBaseSVG:location];
// CPU-only code
SVGKImage *iconImage = [Settings getIconImage:location withBaseSVG:baseIcon];
UIImage *svgImage = iconImage.UIImage; // Converting SVGKImage to UIImage is expensive, so don't do this on the main thread
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Code to be executed on the main thread when background task is finished
if (svgImage) {
[iconImgView setImage:svgImage];
}
}];
}];
最佳答案
而不是直接将GCD与并发队列一起使用,请使用NSOperationQueue
。将其maxConcurrentOperationCount
设置为合理的值,例如4或8。
如果可以的话,还应该将I/O与纯计算分开。对I/O使用限制宽度的操作队列。可以使用无限制的操作队列或纯GCD进行纯计算。
原因是I/O块。 GCD检测到系统处于空闲状态,并启动另一个工作线程,并从队列中启动另一个任务。这也会阻塞I/O,因此它会做更多的工作,直到达到极限为止。然后,I/O开始完成,任务解除阻塞。现在您已超额预订了系统资源(即CPU),因为正在运行的任务多于核心,并且突然间它们实际上正在使用CPU而不是被I/O阻塞。
纯粹的计算任务不会引发此问题,因为GCD认为系统实际上很忙,在更早的任务完成之前不会使更多任务出队。
关于ios - 如何在不达到全局GCD限制的情况下并行处理许多(100+)个任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30933323/
我是一名优秀的程序员,十分优秀!