2009-07-17 17 views
0

Ich versuche meinen Weg durch Obj-C zu finden, um ein iPhone-Spiel zu bauen.insertObject fügt kein Objekt hinzu?

Ich möchte ein Array von Objekten für die spätere Verwendung erstellen. Hier ist, was ich versucht:

NSMutableArray  *positionIcons; 
[positionIcons insertObject:annotation atIndex:0]; 
positionIcons = [NSArray arrayWithObjects:annotation, nil]; 

Die insert Linie verlässt die Zählung bei 0. Allerdings ist die nächste Zeile korrekt das Objekt einfügt (und zählen bewegt zu 1). Was gibt?

Antwort

7

Sie müssen positionIcons initialisieren, ändern Sie den Code:

NSMutableArray *positionIcons = [[NSMutableArray alloc] init]; 
[positionIcons insertObject:annotation atIndex:0]; 
positionIcons = [NSArray arrayWithObjects:annotation, nil]; 
+0

wow -. schnell und perfekt ich habe meine Haare wurde zerreißen – BankStrong

4

@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:

  1. 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.
  2. 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).
  3. 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

+0

dank -.. das Gedächtnis Leck Problem war in meinem Code (und ich bin sicher, dass msaeed nicht durch gleichzeitige Fixierung zu verwechseln wollte). Ich lecke wissentlich Erinnerungen durch, während ich Obj-C lerne. Ich plane, zurückzugehen, nachdem ich mehr Wissen habe, um nach mir zu fegen.Ihr Beispiel ist dafür großartig. – BankStrong

+0

Es macht keinen Spaß /: Ich habe seit 2008 eine Menge gelernt und jetzt, wo ich endlich MASSIVE Projekte mache, stürzen meine Apps ab und ich muss zurückgehen und all das lernen !!! Gedächtnis ARGHHH –

Verwandte Themen