ivars以及如何正确实例化其值(iPhone)

时间:2010-03-01 13:38:05

标签: objective-c properties

我已经开发了一段时间的应用程序,现在我已经开始使用“Instruments-Leaks”部分了。

我记得在我学习的几个月前,有些东西让我感到困惑。我把整个事情都用在信仰上,并按照Apple和其他人的方式进行。据我所知,SDK生成的访问器将负责内存管理。

但是伊娃如何自己初始化?

如果我的界面中有这样的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];

它会起作用但显然会泄漏内存。

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

它是否与ivar类型为NSArray / NSMutableArray特别有关,我不记得它是其他ivars的问题。

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

有人请帮助我概述“从”开始的正确方法:@property() - > @synthesize - >使用ivar - > dealloc?

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

2 个答案:

答案 0 :(得分:2)

所有ivars最初都设置为nil,因此您需要在使用前对其进行实例化。很难说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.  

答案 1 :(得分:0)

我的理解是

self.results = anArray;

相同
[self setResults:anArray];

因为在这种情况下结果是属性。

setResults:的实现方式由@property设置(在这种情况下,它将保留新值)。所以这意味着anArray的保留计数为1.设置self.results后,anArray的保留计数为2.这就是你想释放以前使用的anArray的原因。 也就是说,我不明白为什么setResults:在你设置它时会崩溃。 (也许它只是在你尝试使用self.results时崩溃,而不是设置它?) 我自己只是一个初学者,如果出现问题,我强烈鼓励所有读这篇文章的人告诉我什么是错的或正确的。还是自己学习。

Apple会这样做的方式:

在.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];
}