I have the following variable defined:
@property (nonatomic, retain) NSMutableArray *arraySpeechSentences;
And I am trying to initialise it in the following way:
// Set the array of sentences to the stored array
NSMutableArray *speechSentences = [[NSMutableArray alloc] initWithArray:[tempDict objectForKey:key]];
arraySpeechSentences = speechSentences;
[speechSentences release];
When I try to call [arraySpeechSentences count] the application crashes. However, if I set the variable in the following way:
// Set the array of sentences to the stored array
NSMutableArray *speechSentences = [[NSMutableArray alloc] initWithArray:[tempDict objectForKey:key]];
self.arraySpeechSentences = speechSentences;
[speechSentences release];
I can call [arraySpeechSentences count] perfectly fine. I was under the impression that if you use self. it simply checks to see if variable is already set, and if so it will release the object before assigning it the new value. Have I got this wrong, and if so when should I be using self. to set values?
Thanks for any help,
Elliott
I’ll try to give a detail answer for this.
First when you use
@property/@synthesizedirective you create getter and setter methods around a variable.In your case, the variable is called
arraySpeechSentences(the compiler will create the variable for you) and you can access these methods (setters and getters) withself..is the same as
And
is equal to
In the first snippet of code
arraySpeechSentencespoints to the same objectspeechSentencespoints to. But when you do[speechSentences release]you dealloc that object and nowarraySpeechSentencesis a dangling pointer. You receive a message sent to a deallocated instance I suppose. Try to enable Zombie to see it.Speaking in terms of retain count, the array has a retain count of 1 when you do
alloc-init.But when you
releaseit, the retain count goes to zero, the object doesn’t exist anymore and you have a crash when you try to accessarraySpeechSentences.Instead, when you deal with properties, the policy applied to a variable is important. Since the property use a
retainpolicy, when you set an objectthe retain count for the referenced object is increased. Under the hood, saying
self.arraySpeechSentences = // somethingis equal to call the setter likeThe second snippet work since the retain count for your object is one when you do
alloc-init, becomes two when you callself.arraySpeechSentences =and returns to one when you do the release. This time, the object is maintained alive since it has a retain count of 1.If you have a property with a
retainorcopypolicy, don’t forget to release the object indealloclike, otherwise you can have leaks.To understand how Memory works I suggest to read MemoryManagement Apple doc.
P.S. Starting from iOS 5 there is a new compiler feature, called ARC (Automatic Reference Counting), that allows you to forget about
retain/releasecalls. In addition, since it forces you to think in terms of object graphs, I suggest you to take a look into.Hope that helps.