我正在尝试在后台线程上进行一些“屏幕外渲染”,以更新我正在创建的类似设计器的应用的预览。
我在NSOperationQueue派生的队列中使用renderInContext
来完成此操作,但请注意它很慢。
所以,我开始使用drawViewHierarchyInRect
,效果很好而且速度更快。但是,我注意到当这个方法以b / g运行时,我的UI完全阻塞。
如果我在主线上这样做......
UIView *preview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
preview.backgroundColor = [UIColor redColor];
UIGraphicsBeginImageContextWithOptions(preview.bounds.size, NO, 0.0);
BOOL ok = [preview drawViewHierarchyInRect:preview.bounds afterScreenUpdates:YES];
UIImage *img = nil;
if( ok )
{
img = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();
......一切正常。
但是,如果我(比如说)发送这个......
if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW) == 0)
{
dispatch_async(renderQueue, ^{
// capture
UIView *preview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
preview.backgroundColor = [UIColor redColor];
UIGraphicsBeginImageContextWithOptions(preview.bounds.size, NO, 0.0);
BOOL ok = [preview drawViewHierarchyInRect:preview.bounds afterScreenUpdates:YES];
UIImage *img = nil;
if( ok )
{
img = UIGraphicsGetImageFromCurrentImageContext();
}
UIGraphicsEndImageContext();
}
dispatch_semaphore_signal(semaphore);
});
...我的用户界面在执行完毕后冻结了。
'ok'返回YES,所以似乎一切正常。
如果我将afterUpdates设置为NO,则'ok'为NO(失败),但UI仍然会响应。
使用drawViewHierarchyInRect除主线程以外的任何东西都有限制吗?
答案 0 :(得分:2)
UIKit对象只能在主线程上操作。 Apple的UIKit documentation提到了这个说法
在大多数情况下,只能从应用程序的主线程中使用UIKit类。这是 特别适用于从UIResponder派生的类或涉及的类 以任何方式操纵您的应用程序的用户界面。
答案 1 :(得分:0)
您是从主线程调用上述dispatch_async
吗?我的理论是你用[preview drawViewHierarchyInRect:preview.bounds afterScreenUpdates:YES];
调用YES
需要在主线程上执行一些代码,但主线程在信号量上被阻塞。您可能想要做的是偶尔屈服于主线程,以便drawViewHierarchyInRect
可以完成。
__block dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(renderQueue, ^{
/// your code here
/// ...
BOOL ok = [preview drawViewHierarchyInRect:preview.bounds afterScreenUpdates:YES];
.....
dispatch_semaphore_signal(sema);
});
while (dispatch_semaphore_wait(sema, DISPATCH_TIME_NOW)) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
}