相关视图消失后调用的CATiledLayer drawInContext

时间:2010-10-27 00:27:27

标签: ios calayer catiledlayer

今天我遇到了一个涉及CATiledLayer的有趣的iOS问题。这只发生在设备上 - 而不是在模拟器中。

我的视图通过drawLayer:inContext:delegate callback在其CALayer中绘制。该图层有一个CATiledLayer派生的子图层,它在重写的drawInContext:方法中执行自己的绘图。

两个图层都通过CGContextDrawPDFPage()呈现pdf内容。 (CALayer绘制低分辨率版本,而CATiledLayer子层在顶部绘制高分辨率内容。)

我遇到了一个我将完成视图的场景 - 将其从超级视图中删除并释放它。在视图上调用dealloc()。稍后,系统将调用CATiledLayer的drawInContext:方法(在后台线程上)。它会绘制,但是从方法返回时,Springboard会崩溃,并且这样做也会导致我的应用程序崩溃。

我通过在视图的dealloc方法中设置CATiledLayer中的标志来修复它,告诉它不再渲染。

但我只能想象有一种更优雅的方式。为什么仍然在父图层之后调用CATiledLayer drawInContext:方法,并且父图层的视图被解除分配?关闭视图的正确方法是什么,以免发生这种情况?

4 个答案:

答案 0 :(得分:9)

缓慢但最好的解决方法是设置view.layer.contents = nil。这等待线程完成。

答案 1 :(得分:3)

在发布视图之前将view.layer.delegate设置为nil。

答案 2 :(得分:0)

-(void)drawLayer:(CALayer *)calayer inContext:(CGContextRef)context {    
   if(!self.superview)
      return;
   ...

更新:我记得,在旧版本的iOS中遇到CATiledLayers时出现问题,但在dealloc之前将委托设置为nil是现在的方法。请参阅:https://stackoverflow.com/a/4943231/2882

答案 3 :(得分:0)

这花了很长时间。我最新的方法是在viewWillDisappear方法中声明一个块变量并赋值给self。然后调用setContents调用到全局调度队列 - 无需锁定主线程。然后当setContents返回调用回主线程并将块变量设置为nil时,这应该确保在主线程上释放视图控制器。但有一点需要注意,我发现使用dispatch_after调用主线程是明智的,因为全局调度队列会保留视图控制器,直到它退出块,这意味着它可以在它退出(和释放)之间存在竞争条件视图控制器)和主线程块将块变量设置为nil),这可能导致在全局调度队列线程上释放。