我定义了以下变量:
@property (nonatomic, retain) NSMutableArray *arraySpeechSentences;
我正在尝试通过以下方式对其进行初始化:
// Set the array of sentences to the stored array
NSMutableArray *speechSentences = [[NSMutableArray alloc] initWithArray:[tempDict objectForKey:key]];
arraySpeechSentences = speechSentences;
[speechSentences release];
当我尝试调用[arraySpeechSentences count]时,应用程序崩溃了。但是,如果我通过以下方式设置变量:
// Set the array of sentences to the stored array
NSMutableArray *speechSentences = [[NSMutableArray alloc] initWithArray:[tempDict objectForKey:key]];
self.arraySpeechSentences = speechSentences;
[speechSentences release];
我可以称呼[arraySpeechSentences count]非常好。我的印象是,如果你使用自我。它只是检查变量是否已设置,如果已设置,它将在分配新值之前释放该对象。我是否理解错了?如果是,我应该何时使用自我。设置值?
谢谢你的帮助,
艾略特
最佳答案
我将尝试为此提供详细的答案。
首先,当您使用@property/@synthesize
指令时,您将围绕变量创建getter和setter方法。
在您的情况下,该变量称为arraySpeechSentences
(编译器将为您创建变量),您可以使用self.
访问这些方法(setter和getter)。
self.arraySpeechSentences = // something
是相同的
[self setArraySpeechSentences:something]; // setter
和
NSMutableArray* something = self.arraySpeechSentences;
等于
NSMutableArray* something = [self arraySpeechSentences]; // getter
在第一段代码中
NSMutableArray *speechSentences = [[NSMutableArray alloc] initWithArray:[tempDict objectForKey:key]];
arraySpeechSentences = speechSentences;
arraySpeechSentences
指向同一对象speechSentences
指向。但是,当您执行[speechSentences release]
时,便会释放该对象,而现在arraySpeechSentences
是一个悬空的指针。我想您会收到一条发送到已释放实例的消息。尝试使僵尸看到它。说到保留计数,当您执行
alloc-init
时,数组的保留计数为1。但是,当您
release
使用它时,保留计数将变为零,该对象不再存在,并且尝试访问arraySpeechSentences
时会崩溃。相反,当您处理属性时,应用于变量的策略很重要。由于该属性使用
retain
策略,因此在设置对象时self.arraySpeechSentences = // something
被引用对象的保留计数增加。在幕后,说
self.arraySpeechSentences = // something
等于称呼二传手- (void)setArraySpeechSentences:(NSMutableArray*)newValue
{
// pseudo code here...
if(newValue != arraySpeechSentences) {
[arraySpeechSentences release];
arraySpeechSentences = [newValue retain];
}
}
第二个代码段工作是因为对象的保留计数在执行
alloc-init
时为1,在调用self.arraySpeechSentences =
时变为2,在执行释放时返回为1。这次,由于保留计数为1,因此该对象保持活动状态。如果您拥有具有
retain
或copy
策略的属性,请不要忘记像dealloc
那样释放对象,否则可能会泄漏。- (void)dealloc
{
[arraySpeechSentences release];
[super dealloc];
}
为了了解内存的工作原理,我建议阅读MemoryManagement Apple doc。
附言从iOS 5开始,有一个称为ARC(自动引用计数)的新编译器功能,可让您忘记
retain/release
调用。另外,由于它会迫使您根据对象图进行思考,因此建议您进行研究。希望能有所帮助。