【问题标题】:Incorrect decrement of reference count for retained property保留属性的引用计数减少不正确
【发布时间】:2012-04-14 14:54:29
【问题描述】:

我想我还是不明白这一点。我没有在这个项目上使用 ARC。

对于使用retain 属性声明的属性aProperty,我希望分配的对象在以下语句中被保留两次:

self.aProperty = [UIView alloc] init...];

一次来自alloc,一次来自setter。

所以我立即释放对象一次,像这样:

self.aProperty = [UIView alloc] init...];
[self.aProperty release];

编译器给出错误信息:

此时不拥有的对象的引用计数减量不正确 由来电者。

此时保留计数是否由 setter 递增,使其变为 2?

另外,“调用者此时不拥有”是什么意思?这可能是我不熟悉的问题。

【问题讨论】:

标签: objective-c memory-management


【解决方案1】:

也许它会警告您,因为该对象未声明为简单变量,而是由其他东西拥有(在本例中为 self),并希望阻止您随机释放对象。

试试这个:

UIView *view [UIView alloc] init...];
self.aProperty = view;
[view release];

或者这个,我通常做的:

self.aProperty = [[[UIView alloc] init] autorelease];

【讨论】:

  • 我这样做了:[dataToBeLoaded_release];错误消息消失了。这使您看起来好像不应该释放该财产。我仍然需要有人验证它已被保留两次并需要释放。 (我尽可能避免自动释放,以使池尽可能小。)
  • autorelease 工作得非常好,真的。即使多次使用它,我也没有注意到对性能有任何不良影响。也许编译器甚至优化该代码以在没有autorelease 的情况下工作?
  • 对象确实得到了两次retained,因此需要release。要解除分配对象,请向其发送第二条释放消息(您可能在对象自己的-dealloc 中执行此操作)
  • NSObject 继承的init 方法什么也不做;实际上是alloc 设置了初始保留计数。您可能想要编辑您的答案。
【解决方案2】:

澄清正在发生的事情。

self.myVar = [[UIView alloc] initWithFrame:frame];

相当于调用

[self setMyVar:[[UIView alloc] initWithFrame:frame]];

当使用带有保留的@property 时,它的实现最终会看起来像这样(这只是一个粗略的例子)

- (void)setMyVar:(UIView *)myVar;
{
    if (_myVar != myVar) {
        [_myVar release];
        _myVar = [myVar retain];
    }
}

所以现在我们可以这么说

+----------- +1 retain ------------+
|                                  |
[[UIView alloc] initWithFrame:frame]

+------ +1 retain ----+
|                     |
_myVar = [myVar retain];

计数为 +2。然后我们会有类似的东西

- (void)dealloc;
{
    [_myVar release];
    [super dealloc];
}

这是-1,这只会给我们留下内存泄漏,因为仍然有+1保留。

我喜欢的模式是

UIView *myVar = [[UIView alloc] initWithFrame:frame];
self.myVar = myVar;
[myVar release]; myVar = nil;

以便尽快释放内存,并且不会留下任何悬空指针,因为它是nil'led out

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    相关资源
    最近更新 更多