在iPhone上通过在后台线程渲染UIWebView来创建UIImage

9
有没有人知道如何获取从UIWebView渲染的UIImage的方法,或者有创意的想法?问题是必须在后台线程上完成。
我来详细说明一下:我试图每秒从多个UIWebView中获取图像,并在屏幕上显示它(当然是iPhone)。由于将层渲染到CGContext是一个占用CPU资源的任务,我不想使用主线程,以免挂起UI。
到目前为止,我的尝试有:
- 我尝试在webView的层上使用renderInContext到UIGraphicalContext,但是_WebTryThreadLock错误会导致webview崩溃。 - 我尝试创建一个CGBitmapContext,并将webview的层渲染到其中,但得到了相同的结果。 - 我尝试实现一个copy方法(通过添加类别)到CALayer,深复制所有公共属性和子层。之后,我尝试渲染我复制的层。我得到了一个部分“正确”的UIImage——也就是说,并没有渲染所有的层,因此例如只获得网站标题(或页脚、正文、搜索栏或仅一些帧)。UIWebview的层包括各种子类化的CALayer,所以这可能就是为什么这种方法不起作用的原因。 - 我尝试在CATransaction中设置kCATransactionDisableActions,但似乎并没有改变这种行为(两者都没有)。
我几乎要放弃了。有没有人能帮忙解决?
2个回答

4

UIWebView十分反感,我是说真的非常反感,在后台线程上进行任何操作。UIKit并不完全支持多线程。绘图到图形上下文是可以的(这在iOS 4中添加),但在辅助线程上创建UIView则不行。

您是否在主线程之外创建了UIWebView?您是否有一些可以分享的代码?我怀疑您的问题是由于您试图在辅助线程上执行对UIWebView的操作所导致的。将视图的内容呈现为图像的绘制操作可以在主线程之外发生,但创建视图本身不行。


3
我正在主线程上创建UIWebViews。我非常同意“讨厌”的部分;),我也同意绘制到图形上下文是可能的,但不幸的是,在某些情况下,似乎呈现UIWebView布局会锁定与UIWebView本身相关联的线程(不是主线程,而是iOS创建的用于处理它的线程),这会导致在由辅助线程执行锁定时出现故障。 UIWebView布局是使用CALayer的一些私有API子类(WebLayer等)构建的。 - Gilbert
我之前在webviews上也遇到过类似的问题,尽管它们也被限制在模拟器中 - 你是对的,这可能与其中一个私有子类有关。很抱歉我不能提供更多帮助。 - lxt

0
我也在处理这个问题。
在一个线程中,我创建了一个视图层级,并通过循环等待网页视图加载完内容。
我创建的 webview 位于 UIViewController 的 viewdidload 中 - 我尝试过做过...
if ([NSThread isMainThread] == NO) {[self performselectorOnMainThread: @selector(viewDidLoad)return;)}

我对dealloc'ing webView也做了同样的事情。

但那行不通...我只发现在自动释放池之前避免UIWebView异常...

我正在使用工具来找出为什么。

这是我的攻击策略... 我将在主线程上使用一个离屏视图执行渲染操作,同时运行一个独立的线程来管理它们的某种类型的队列。我担心会有UI滞后,所以它必须相当高效。


是的,这就是诀窍...使用选择器在单独的线程上创建渲染,查询子线程上的加载状态,然后在准备好时在主线程上进行渲染。 - user438350
2
这基本上是我的当前解决方案。但它并不好,因为我有太多的UI延迟(而且我在主线程上做的唯一事情就是实际的核心渲染过程)。 - Gilbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接