【问题标题】:CALayer addSublayer increasing retain count?CALayer addSublayer 增加保留计数?
【发布时间】:2009-02-20 22:24:41
【问题描述】:

我认为当我将视图添加为这样的子视图时:

UIView* view = [[UIView alloc] init];
[self addSubview:view];
[view release];

之后释放视图是安全的...对于 CALayer 对象是否相同?如果我使用 alloc/init 创建一个 CALayer,然后执行以下操作:

[self.layer addSublayer:layer];

之后释放层是否安全?

【问题讨论】:

    标签: objective-c iphone cocoa-touch


    【解决方案1】:

    是的。一般来说,如果对象 A 需要对象 B,则对象 A 有责任保留它。因此,如果“self.layer”需要“layer”,它会在 addSublayer: 期间碰撞 retainCount,并在不再需要时释放 layer。虽然有一些例外,但这些例外往往有很好的记录。

    【讨论】:

    • 好像是这样。我们有自己的自定义层,所以我们正在做 alloc/init 而不是层,但调整我们的版本似乎已经解决了我们的问题。 :)
    • 更正:我看到的问题是,如果你“从超级层中删除”,那么即使在同一个代码块中,对象也可以被销毁。即,如果您随后再次调用“layer.sublayers”,则数组中的一半元素是无效引用,这将使您的应用程序崩溃。 AFAICT 这对 Apple 来说是不正确的 - 在 RunLoop 再次启动之前不会发生这种情况。我刚刚遇到了这个问题。我很想看到一些“有据可查”的案例的链接——也许需要一个文档错误? :)
    【解决方案2】:

    我同意路易斯的观点。尽管在这种情况下这并不是真正必要的,但请注意,您以后可以随时使用retainCount: 方法来仔细检查这些内容。例如:

    NSLog(@"Retain count before: %d", [layer retainCount]);
    [self.layer addSublayer:layer];
    NSLog(@"Retain count after: %d", [layer retainCount]);
    

    【讨论】:

    • retainCount 因为没有实际工作而臭名昭著。我猜这就是你被否决的原因(尽管如果被否决者发表评论会很好)
    • retainCount 工作正常;您只需要记住autorelease 不会立即修改保留计数。只有实际的retainrelease 消息会减少保留计数(在当前自动释放池耗尽之前,不会发送与autorelease 对应的release 消息)。也就是说,使用retainCount 进行任何除了调试是一种可怕的代码气味。
    【解决方案3】:

    首先,你使用 layer 类的方法而不是 alloc/init 创建一个新的 CALayer 对象。像这样:-

    CALayer *l = [CALayer layer];
    l.frame = CGRectMake(...);
    l.position = CGPointMake(...);
    l.anchorpoint = CGPointMake(0,0);
    l.contents = (id)someCGImageRef;
    [self.layer addSublayer:l];
    

    其次,这是您可能会遇到问题的地方,因为如果您在将 CALayer 作为子层添加到视图的主层后释放它,您将遇到崩溃。或者至少我做到了,我认为这是因为 layer 类方法将层添加到自动释放池中,所以如果你自己释放它,你会得到一个双重释放,所以即使他视图的主层仍在使用它,它也会被释放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      相关资源
      最近更新 更多