今天我遇到了一个涉及CATiledLayer的有趣的iOS问题。这只发生在设备上 - 而不是在模拟器中。
我的视图通过drawLayer:inContext:delegate callback在其CALayer中绘制。该图层有一个CATiledLayer派生的子图层,它在重写的drawInContext:方法中执行自己的绘图。
两个图层都通过CGContextDrawPDFPage()呈现pdf内容。 (CALayer绘制低分辨率版本,而CATiledLayer子层在顶部绘制高分辨率内容。)
我遇到了一个我将完成视图的场景 - 将其从超级视图中删除并释放它。在视图上调用dealloc()。稍后,系统将调用CATiledLayer的drawInContext:方法(在后台线程上)。它会绘制,但是从方法返回时,Springboard会崩溃,并且这样做也会导致我的应用程序崩溃。
我通过在视图的dealloc方法中设置CATiledLayer中的标志来修复它,告诉它不再渲染。
但我只能想象有一种更优雅的方式。为什么仍然在父图层之后调用CATiledLayer drawInContext:方法,并且父图层的视图被解除分配?关闭视图的正确方法是什么,以免发生这种情况?
答案 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),这可能导致在全局调度队列线程上释放。