UIView 支持层 - 委托是僵尸

发布于 2024-10-30 08:33:43 字数 935 浏览 0 评论 0原文

我有一个 UIView 类,它使用自定义 CALayer 派生的支持层。即,我有一个静态的 LayerClass 方法,它返回我的自定义 CALayer 类的类。

+ (Class)layerClass
{
    return [CellLayer class];
}

在此类 (CellLayer) 中,我将委托强制转换为包含支持层的 UIView 类 - 具体而言,在 drawInContext: 方法中,我执行以下操作:(

CellClass* cell = (CellClass*)self.delegate;

CellCass 是 UIView 的子类)

其中 看起来工作正常,除了有时调用 drawInContext: 方法并且委托是僵尸(NSZombieEnabled 设置为 TRUE)。

看起来发生的情况是,当单元格对象从其超级视图(即 UIScrollView)中删除时,单元格在释放支持层之前被释放,并且支持层获得 drawInContext: 调用。 NSLog 语句显示最终调用了两个 dealloc 方法(即 UIView 和 CALayer 的 dealloc 都被调用),但我无法确定顺序,因为使用它的应用程序有几十个这样的单元格 - 我想我可以更改 NSLog 以在控制台中显示单元格的地址并匹配 UIView dealloc 和 CALayer dealloc,但我懒得这样做。

我的期望是支持层将在包含它的 UIView 之前释放。

这是正确的行为吗?我当前的解决方法是,在 UIView 的 dealloc 中,我在支持层 (viewWasReleased) 中设置了一个标志,并且在 drawInContext 中,如果设置了该标志,我只需返回即可。

有没有更好、更干净的方法来做到这一点?

I have a UIView class which uses a custom CALayer-derived backing layer. i.e., I have a static layerClass method which returns the class of my custom CALayer class.

+ (Class)layerClass
{
    return [CellLayer class];
}

Within this class (CellLayer) I cast the delegate to the class of the UIView which contains the backing layer - specifically, within the drawInContext: method I do this:

CellClass* cell = (CellClass*)self.delegate;

(where CellCass is a subclass of UIView)

This appears to work fine except that sometimes the drawInContext: method is called and the delegate is a zombie (NSZombieEnabled is set TRUE).

It appears that what is happening is that when the cell object is removed from its superview (which is a UIScrollView) the cell is released before the backing layer is released and the backing layer gets a drawInContext: call. NSLog statements reveal that BOTH dealloc methods are eventually called (ie. the UIView and the CALayer's dealloc are both called) but I can't tell for sure what order since the app using this has dozens and dozens of these cells - I guess I could change the NSLog to display the cell's address in the console and match up a UIView dealloc and a CALayer dealloc, but I haven't bothered to do this.

My expectation was that the backing layer would be released before the UIView which contains it.

Is this the correct behavior? My current workaround is that in the UIView's dealloc I set a flag in the backing layer (viewWasReleased) and in the drawInContext I simply return if this flag is set.

Is there a better, cleaner way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

假装爱人 2024-11-06 08:33:43

今天我有同样的问题,我终于解决了我的问题。

问题是,当调用方法 dealloc 时,您的 CellLayer 不会被销毁,因为它具有对当前对象的引用。 (委托)因此 CALayer 不会被销毁,并且 self.delegate 是一个已释放的实例。僵尸一号。

我修复了在我的类 viewDidDisappear 方法中添加的问题,并在那里添加了下一个代码:

if(cell != nil)
    cell.delegate = nil;

然后,当在我的对象中调用 dealloc 方法时,CALayer 中没有对其的引用,因此使用简单的 self.cell = nil; CALayer 对象之前将被销毁,并且委托不会出现问题。

today I had the same question and I finally fixed my problem.

The problem was that when the method dealloc is called, your CellLayer is not destroyed because it has a reference to the current object. (the delegate) So CALayer is not destroyed and the self.delegate is an deallocated instance. The zombie one.

I fixed that adding in my class viewDidDisappear method, and there I have added the next code:

if(cell != nil)
    cell.delegate = nil;

Then when the dealloc method is called in my object there is not reference in CALayer to it so with a simple self.cell = nil; The CALayer object will be destroyed before and you won't have the problem with the delegate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文