Vous devez lire le Cocoa Memory Management Guide. Certaines des choses que vous faites dans le code montrent que vous ne maîtrisez pas les concepts fondamentaux de la gestion de la mémoire cacao.
Par exemple:
[Foo alloc];
Vous n'êtes pas initialisant 'foo'. Il est de pratique courante de coupler alloc
et init
appels ensemble, par exemple: [[Foo alloc] init];
Cela garantira que les objets membres et l'état est ce que vous attendez après la création.
name2 = [foo bar]; // returns a (NSString *)
Le procédé bar
est susceptible de renvoyer une chaîne autoreleased
.Vous ne le retenez pas après l'avoir affecté à name2
, il sera donc désalloué quelque temps après le retour de la méthode. Et c'est pourquoi votre code plante. Vous essayez d'accéder à un objet désalloué. L'objet pointé par name2
a été libéré et désalloué, mais le pointeur n'a pas été défini sur zéro, ce qui signifie que la mémoire vers laquelle il pointe peut maintenant contenir n'importe quoi. C'est indéfini.
La raison pour laquelle fonctionne name1
est due à une attention particulière à l'utilisation des chaînes littérales @ "" dans Cocoa. Quand une chaîne est utilisée comme ça, elle devient "intériorisée". Si vous créez deux chaînes littérales contenant le même texte, le système l'optimisera afin que ces deux chaînes pointent vers un objet en mémoire.
C'est-à-dire que si vous avez du code qui ressemble à ceci:
NSString *myString1 = @"hello";
NSString *myString2 = @"hello";
NSLog(@"string1: %p, string2: %p", myString1, myString2);
il en résulterait un message ressemblant à: string1: 0x123456, string2: 0x123456
. La chose importante à noter ici est que les adresses de mémoire sont les mêmes. Les chaînes pointent sur le même objet, même s'il s'agit d'instances différentes dans le code.