【问题标题】:CGLayerRef in NSValue - when to call retain() or release()?NSValue 中的 CGLayerRef - 何时调用 retain() 或 release()?
【发布时间】:2011-08-28 10:36:58
【问题描述】:

我将一些图形缓存到 CGLayers 上,然后使用 @encode 将它们存储在 NSValue 对象中(以便将它们存储在数组中)。我只是想确保我正确处理保留/释放...

我缓存图形并将它们存储在数组中,如下所示:

// Create an NSMutableArray "newCache"
CGLayerRef drawingLayer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef drawingContext = CGLayerGetContext(drawingLayer);

// Do some drawing...

[newCache addObject:[NSValue valueWithBytes:&drawingLayer objCType:@encode(CGLayerRef)]];
CGLayerRelease(drawingLayer);      // Is this release correct?

然后我检索图层:

CGLayerRef retrievedLayer;
[(NSValue *)[cacheArray objectAtIndex:index] getValue:&retrievedLayer];

// Use the layer...

// Should I release retrievedLayer here?

我是否认为该层在添加到数组后需要释放(第一个代码 sn-p 中的最后一行)?我假设是这种情况,因为我在代码的前面调用了一个 create 函数。然后 NSValue 会为我跟踪图层数据吗?检索到的Layer在使用后需要手动释放吗?

谢谢

【问题讨论】:

  • 您使用数组有什么原因吗?当内存不足时,您可能会发现 NSCache 更易于使用且更有帮助。
  • 公平一点 - 不,我只使用一个数组,因为有足够的层需要一个集合。我以前没有真正使用过 NSCache,但这看起来可能是它的理想选择。

标签: ios memory-management core-graphics release-management cglayer


【解决方案1】:

NSValue 不知道 Core Foundation 类型,因此它不会保留或释放 CGLayer。 (@encoded 类型的字符串几乎只是告诉它值有多大;它没有告诉它任何有关内存管理的信息。)

在完全完成层和 NSValue 之前,您不得释放层。

或者,更好的是,将 CGLayer 放入数组中。出于内存管理的目的,所有 Core Foundation 对象都与 NSObjects 兼容(discussed previously),这具有您可以将 CF 对象放入 NSArrays 的实际效果,反之亦然。由于 CGLayer 是 CF 对象,这意味着您可以将 CGLayer 放入数组中,而无需将其装箱到另一个对象中。

【讨论】:

  • 感谢您的回复。我现在已经解决了这个问题——因为每一层都可以被多个单独的类保留,我发现很难正确处理这些版本。我没有考虑到实现缓存的类中的“原始”层,因为我意识到在将它存储在数组中后我无法立即释放它。我最终遍历了 dealloc 中的缓存数组以释放任何挂起。再次感谢。
  • @StuDev:数组保留了它们的内容,所以如果你把CGLayers直接放到数组中,数组会保留它们。这也适用于 NSCache。
  • 我的想法是否正确,因为 CGLayers 是通过 valueWithBytes:objCType: 插入到数组中的,所以 CGLayers 实际上并没有被数组保留?相反,我只是在将 CGLayers 插入到数组中时没有释放它们以保留它们。我不得不遍历 dealloc 中的数组以找到对层的引用并调用 CFRelease() 方法,因为数组似乎不会为 CF 类型执行此操作。
  • @StuDev:正确。您没有(直接)将 CGLayers 插入到数组中;你插入了 NSValue 对象。该数组保留了 NSValue 对象,因此在 dealloc 时释放 NSValue。它不知道也不关心 NSValue 对象拥有的任何对象,因为它不应该——这将违反内存管理规则。数组中的对象——NSValues——负责释放它们拥有的任何对象,并且它们不拥有(保留)CGLayer 对象。这就是为什么最好将 CGLayers 直接放入数组中:然后数组将保留和释放它们。
  • 如何将 CGLayers 直接放入数组中?我需要使用 CFArray 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多