@msaeed hat die richtige Antwort, aber es lohnt sich ein wenig mehr Zeit auf diesem Codefragment zu nehmen, weil es Speicherlecks.
The iPhone doesn't support garbage collection, daher ist es wichtig zu verstehen, wie das halbautomatische Speichermanagement von Objective-C funktioniert. Apple has a good reference here, aber das Wesentliche davon ist, dass Sie dafür verantwortlich sind, die "Retain-Anzahl" Ihrer Objekte beizubehalten. Wenn Sie ein Objekt mit einer Instanzmethode -init
initialisieren (z. B. [[NSMutableArray alloc] init]
in Ihrem Beispiel, aber auch jede andere mit "init" beginnende Methode wie [[NSMutableArray alloc] initWithCapacity:42]
), hat das neu initialisierte Objekt eine Retain-Anzahl von 1. Nachfolgende Aufrufe der Methode -retain
dieser Instanz Inkrementieren Sie die Retain-Anzahl, während Aufrufe der -release
-Methode der Instanz die Anzahl dekrementieren.Wenn die Zählung 0 erreicht, wird das Objekt freigegeben, und weitere Versuche, Nachrichten zu senden, führen zu Nullzeiger-Ausnahmen.
msaeed's korrigierter Code, hier ist was passiert, nach Zeile:
- Eine neue Instanz von
NSMutableArray
ist zugewiesen; Es wird die -init
-Methode aufgerufen, die die Instanz initialisiert und die Retain-Anzahl auf 1 setzt. Der Zeiger positionIcons
wird dann auf die Adresse dieser neuen Instanz gesetzt.
- Die
-insertObject:atIndex:
Methode wird auf positionIcons
aufgerufen, und alles ist gut (auch durch Konvention hinzufügen ein Objekt zu einer Sammlung wie NSMutableArray
Inkrementen, dass Objekt behalten Anzahl, die Idee ist, dass die Sammlung jetzt hat in gewissem Sinne "Besitz" von diesem Objekt, und will nicht, dass es von darunter aufgehoben wird).
- Eine neue Instanz von
NSArray
wird zugewiesen, und der Zeiger positionIcons
wird dann auf die Adresse dieser neuen Instanz gesetzt. Da die Anzahl der Retains der Zeile NSMutableArray
von Zeile 1 immer noch 1 ist, wird sie nicht aufgehoben, und da Sie Ihre Referenz verloren haben, können Sie niemals -release
aufrufen, um den Speicher zu löschen. Da ist dein Leck.
Vereinbarungsgemäß gibt es einen Unterschied, wie Sie Objekte, die mit -init
Instanzmethoden im Vergleich zu Klassenmethoden wie +arrayWithObjects:
initialisiert werden (im ersten Fall, müssen Sie das Objekt selbst veröffentlichen, aber im zweiten Fall, der Objekt wird bereits eine -autorelease
Nachricht und wird freigegeben auf dem nächsten durch~~POS=TRUNC durch das Runloop Programm gesendet, es sei denn Du -retain
auf nennen
wow -. schnell und perfekt ich habe meine Haare wurde zerreißen – BankStrong