Objective c IVAR和如何正确实例化其值(iPhone)

Objective c IVAR和如何正确实例化其值(iPhone),objective-c,properties,Objective C,Properties,我已经开发了一段时间的应用程序,现在我已经到了“仪器泄漏”的部分 我记得几个月前在我学习的时候,有一件事让我对ivars感到困惑。我对整个事情有点信以为真,只是按照苹果和其他公司的做法行事。据我所知,SDK生成的访问器将负责内存管理 但是ivar本身是如何初始化的呢 如果我的界面中有这样的ivar @interface { NSArray *results; } @property(nonatomic, retain) NSArray *results;

我已经开发了一段时间的应用程序,现在我已经到了“仪器泄漏”的部分

我记得几个月前在我学习的时候,有一件事让我对ivars感到困惑。我对整个事情有点信以为真,只是按照苹果和其他公司的做法行事。据我所知,SDK生成的访问器将负责内存管理

但是ivar本身是如何初始化的呢

如果我的界面中有这样的ivar

@interface
    {   
    NSArray *results;
    }

    @property(nonatomic, retain) NSArray *results;
    @end

@implementation
@synthesize results;
如果我在运行时尝试执行以下操作:

[self setResults:allReadyInitializedArray];
它将崩溃,告诉我此结果对象未初始化。但是,如果我这样做:

self.results = [[NSArray alloc] init]; //Im assigning this property memory, but hasn't the SDK already done that?
[self setResults:allReadyInitializedArray];
它可以工作,但显然会泄漏内存

我的印象是,使用 访问器将在设置新值之前释放旧值,这意味着 上面的值应该是释放的旧值,新值是+1保留计数

这是否与NSArray/NSMutableArray类型的ivar有关,我想不起来其他ivar也有问题

这个问题在我的XML解析器中尤为突出,我需要不断地设置一个ivar值,使用它,覆盖这个值,使用新值等等

有没有人能帮我概括一下“开始”的正确方式:@property()->@synthetic->使用ivar->解除锁定?


我已经阅读了内存管理文档,我试图寻找一些在我理解范围内的债务文档,但似乎即使我每天都使用IVAR,我也不明白幕后发生了什么。

所有IVAR最初都设置为零,所以在使用之前需要实例化它们。很难说为什么
setResults
在没有看到其实现的情况下会产生错误

self.results = [[NSArray alloc] init];
这里使用alloc方法创建新的数组对象-其保留计数等于1。之后,setter方法再次保留数组,因此第一个保留的对象保持“未处理”,导致内存泄漏。要消除泄漏,您可以重写代码,如下所示:

self.results = [[[NSArray alloc] init] autorelease];
// or
self.results = [NSArray arrayWith...]; // any NSArray's convenience method that returns autoreleased object.  

我的理解是

self.results = anArray;

[self setResults:anArray];
因为在这种情况下,结果是一个属性

setResults:的实现方式由@property设置(在本例中,它将保留新值)。这意味着数组的保留计数为1。设置self.results后,数组的保留计数为2。这就是为什么要释放以前使用的anArray。 也就是说,我不明白为什么setResults:在设置时会崩溃。(可能只有当您尝试使用self.results而不是设置它时,它才会崩溃?) 我自己只是一个初学者,如果有什么不对劲,我强烈鼓励每一个读到这篇文章的人让我知道什么是错的或正确的。我自己还在学习

苹果的做法是:

在.h文件中

@property (nonatomic, retain) NSArray *results
在.m文件中

@synthesize results;

- (id)init {
    NSArray *anArray = [[NSArray alloc] init];    // retainCount = 1
    self.results = anArray;                       // retainCount = 2
    [anArray release];                            // retainCount = 1, only one "left" is in self.results
}

- (void)dealloc {
    [results release];
}

起初你做这件事的方式看起来是对的。你能把你收到的错误信息的确切文本发出去吗?嗨,克里斯布。我发现这篇文章非常有用:我对代码中的每个实例都做了一个regexp(self.*=[.[.]alloc]),但我没有像你和苹果上面描述的那样去做。(那里大约有120个实例!)然后我再次检查了所有代码,并标记了类似“arrayWithArray”这样的操作的发生最后,我将每个dealloc方法都放到@synthesis下,以便更容易地跟踪所有内容。所有这些都让我对IVAR有了更好的理解。谢谢