objective-c "Mutationsmethode an ein unveränderliches Objekt gesendet" -Fehler

7

Ich bin ziemlich neu bei objective-c und versuche, eine kleine App für das iPhone zu erstellen.
Neben diesem kleinen Fehler bin ich fast fertig. Eigentlich habe ich Stunden mit Google gesucht, um eine passende Lösung zu finden, aber leider kann ich keine Lösung finden, die funktioniert.
Ich verwende dieses Lernprogramm hier, um ein UITableView zu erstellen: UITableView-Lernprogramm Die vollständige Fehlermeldung sieht folgendermaßen aus:

  

* App aufgrund der nicht abgefangenen Ausnahme beenden "NSInternalInconsistencyException", Grund: '* - [NSCFArray insertObject: atIndex:]: Die Mutationsmethode wird an das unveränderliche Objekt'

gesendet

Dies ist der Data Controller Header: MyLinksDataController.h

%Vor%

Und die Datenkontrollmethode: MyLinksDataController.m

%Vor%

------------------------------- später im Quellcode ---------- -----------------------

%Vor%

Ich würde jede Hilfe sehr schätzen.

Vielen Dank für Ihre Unterstützung im Voraus.

Daniel

    
John Calsbeek 03.08.2009, 19:00
quelle

5 Antworten

27

Das Senden der copy Nachricht an ein NSMutableArray - wie in der folgenden Anweisung in init - gibt eine unveränderliche Kopie zurück.

%Vor%

In der Kakao-Dokumentation wird das Wort unveränderlich verwendet, um auf schreibgeschützte Objekte zu verweisen, die nach der Initialisierung nicht geändert werden können. Daher schlägt der Aufruf von subsequence zu addObject: mit einer Fehlermeldung fehl.

Beachten Sie, dass die obige Zuweisungsanweisung keine Compiler-Warnung auslöst. copy gibt eine ID zurück, die - soweit der Compiler betroffen ist - in der tableList NSMutableArray * komfortabel Platz findet. Es gibt hier auch keinen Laufzeitfehler, da keine Nachrichten herumgereicht werden; Ein NSArray-Zeiger wird nur in eine NSMutableArray-Zeigervariable eingefügt.

Um eine veränderbare Kopie zu erhalten, verwenden Sie stattdessen mutableCopy .

Beachten Sie, dass sowohl copy als auch mutableCopy ein neues Array erstellen und den Inhalt des Originals dorthin kopieren. Eine Änderung der Kopie wird nicht im Original wiedergegeben. Wenn Sie nur einen anderen Verweis auf das ursprüngliche Array benötigen, verwenden Sie stattdessen beibehalten .

Weitere Informationen finden Sie im Diskussionsabschnitt der Referenz copyWithZone und in der NSMutualCopying-Protokollreferenz .

    
Oren Trutner 03.08.2009 22:40
quelle
5

Sie kennen im Grunde genommen die Speicherverwaltungsregeln von Cocoa ( speziell diese Details ). Wenn ein Objekt mit einer unveränderlichen Version und einer veränderbaren Version vorhanden ist, wird das Senden von -copy an ein Objekt als unveränderlich zurückgegeben Objekt.

Lassen Sie uns durch den relevanten Teil gehen.

%Vor%

Dies erstellt ein neues, leeres veränderbares Array, das Ihnen gehört. Gut.

%Vor%

Dies erstellt eine unveränderliche Kopie des leeren Arrays. Außerdem besitzen Sie diese frisch erstellte Kopie. Das sind zwei Objekte, die du im Moment besitzt.

Damit wird Ihr kopiertes Objekt auch der tableList -Eigenschaft zugewiesen. Schauen wir uns die Deklaration der Property an:

%Vor%

Diese Eigenschaft wird mit copy Attribut . Wenn ein neuer Wert zugewiesen wird, wird eine weitere -copy -Methode an ihn gesendet. Diese dritte Kopie gehört jedoch nicht Ihnen, sondern dem Objekt.

%Vor%

Dadurch wird das ursprüngliche leere veränderbare Array freigegeben. Gut, aber es gibt immer noch den, den du in der zweiten Zeile gemacht hast, unveröffentlicht. Das ist ein Speicherleck.

Wenn Sie tatsächlich eine veränderbare Kopie von etwas benötigen, möchten Sie die Methode -mutableCopy . (Die Dokumentation zu diesen Methoden finden Sie unter NSCopying und NSMutableCopying .) Sie werden nie eine veränderbare Version von etwas in eine Eigenschaft mit dem copy -Attribut bekommen, da es -copy an alles, was ihm zugewiesen ist, sendet. Ihre Eigenschaft sollte das retain -Attribut anstelle des copy -Attributs verwenden, und der Code zum Initialisieren sollte in etwa so aussehen:

%Vor%

Oder eine kürzere Version:

%Vor%

Sie müssen in dieser Situation nichts kopieren, Sie erstellen lediglich ein neues Objekt.

    
John Calsbeek 03.08.2009 23:55
quelle
1

Wenn Sie localList von einem anderen Objekt aus zuweisen, kann es sein, dass es in diesem Fall nicht änderbar ist. Dies kann durch diese Art von Fehler verursacht werden.

Ich hoffe, es wird hilfreich sein.

%Vor%     
Gaurav 14.01.2014 11:47
quelle
0

Hi statt mutableCopy ich glaube " strong " kann auch verwendet werden, um dieses Problem anzugehen. Ich hatte ein ähnliches Problem in meinem Code auch wegen der Verwendung von " copy " anstelle von " strong ". Also die folgende Zeile:

%Vor%

Es sollte sein:

%Vor%

Ich hoffe, es wird für Anfänger, die Fehler wie ich machen, eine große Hilfe sein.

    
Rajeev Kumar Barnwal 25.07.2013 17:55
quelle
0

Dies wird das Problem beheben:

%Vor%     
Asi Givati 18.11.2014 08:14
quelle