【问题标题】:do I need to allocate and init variables with retain properties?(iphone)我需要使用保留属性分配和初始化变量吗?(iphone)
【发布时间】:2011-07-06 16:28:02
【问题描述】:
@interface Approval : NSObject 
{
    NSMutableArray *approvalValues;
}
@property (nonatomic,retain) NSMutableArray *approvalValues;

如果我这样做了,我还需要在 init 方法中调用 `approvalValues = [[NSMutableArray alloc] init] 吗?我的印象是我必须这样做,但它导致了泄漏。在 dealloc 方法中我发布了approvalValues

【问题讨论】:

  • 我刚刚发布了一个答案,假设您的代码有一些问题。下次请尽量发帖,方便其他人回答。
  • 它是如何导致泄漏的?你得到什么样的错误才能说它导致泄漏?你还在使用/分配什么approveValues?你的问题太模糊,无法得到正确的答案。你的问题的答案是肯定的。

标签: iphone objective-c xcode


【解决方案1】:

您需要allocinit approvalValues。问题似乎与您过度保留对象有关。

您的代码可能如下所示:

self.approvalValues = [[NSMutableArray alloc] init];

alloc 将返回一个 retainCount 为 1 的对象,当使用 retain 设置器时,它会被撞到 2。为了解决它,您可能需要在分配之前 autorelease 对象它,编写如下代码:

self.approvalValues = [[[NSMutableArray alloc] init] autorelease];

这将得到一个实例变量,其 retainCount 仅为 1,因此当您 dealloc 对象时它不会泄漏。

【讨论】:

  • 在我看来,在使用属性时,最好在 dealloc 中调用 release,而不是像在 2 中那样调用 autorelease
  • @domino 您仍然需要在dealloc 中输入release。在没有autorelease 的情况下使用self.property = alloc-init 会过度保留对象,这很糟糕。 alloc-init 和属性访问器都保留了对象,所以你需要autorelease 或者使用一个临时变量来分配-init,然后调用访问器,然后释放它。在这两种情况下,您之后都拥有该对象,因此您需要在 dealloc 中释放它。
  • @domino 这个声明self.approvalValues = [[NSMutableArray alloc] init]; 和所有类似self.retainOrCopyProperty = alloc-init 的声明一般都会过度保留导致泄漏的对象并且是错误。阅读我之前评论中的解释或参考this questionthis one
  • 一个对象的绝对retain count是没有意义的;不鼓励使用或考虑。
【解决方案2】:

是的,您仍然需要分配/初始化,但是您只能在 dealloc 方法中释放。

【讨论】:

  • 那么为什么泄漏工具告诉我有泄漏?
【解决方案3】:

在 init 方法中,您通常会直接访问 ivar 并像这样初始化它:

approvalValues = [[NSMutableArray alloc] init];

在 dealloc 中,您将需要这样的 matchin 版本:

[approvalValues release];

通常建议直接在 init 和 dealloc 方法中访问 ivars 以避免任何由 setter/getter 引起的副作用。

在整个课程中,您将希望使用 KVC setter/getter 或点符号来设置这样的对象

// Dot notation
NSMutableArray *tmpApprovalValues = [[NSMutableArray alloc] init];
self.approvalValues = tmpApprovalValues;
[tmpApprovalValues release]; tmpApprovalValues = nil;

// Call to setters/getters
NSMutableArray *tmpApprovalValues = [[NSMutableArray alloc] init];
[self setApprovalValues:tmpApprovalValues];
[tmpApprovalValues release]; tmpApprovalValues = nil;

感谢@Yuji,更正了术语

【讨论】:

  • 严格来说不是KVC。这只是对 setter/getter 的调用...KVC 是通过setValue:forKey:valueForKey: 访问的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 2021-02-25
  • 1970-01-01
相关资源
最近更新 更多