Die richtige Art und Weise zu erklären, alloc, load, und dealloc ein NSMutableArray
Ich erkläre mein array in mein *.h-Datei:
@interface aViewController: UIViewController { NSMutableArray *anArray; //Sie brauchen, um später ändert sich das oft. } @Ende
Ich alloc Speicher für mein es *.m-Datei:
-(void) viewDidLoad { anArray = [[NSMutableArray alloc] init]; }
Ich auf eine test-Taste zum laden meiner array (schließlich müssen die Last VERSCHIEDENE Werte
bei jedem Klick):
anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
Und ich frei es hier:
-(void) dealloc { [anArray release]; [super dealloc]; }
Nicht, dass alle sehen ok?
Weil es abstürzt, wenn ich später dann diesen code ausführen:
NSLog(@"%d", [anArray count]);
Nicht sicher, warum ein einfaches "NSLog() und count" Abstürzen würde, alles.
Dirk,
Lassen Sie es mich so sagen: ich habe eine RIESIGE Missverständnis von Pointern, arrays, strings und Speicher.
Habe ich alles gelesen, was ich finden kann... aber (noch) zu finden, eine einfache, klare, leicht verständliche Beschreibung.
Können Sie vorschlagen? (Hoffentlich weniger als 10 Seiten zu Lesen.)
Gibt es eine Referenz, erklärt NUR diesem Thema... und aus Sicht der "Sie haben 12 Jahre Programmiererfahrung... aber KEINER, der jemals behandelt reservieren von Speicher oder Zeiger".)
Also die variable-name ist NICHT das Weise ich auf das Objekt verweisen?
Dann warum haben es?
Ich bin verwendet, um viele andere Sprachen, die genau dies tun:
myString = "dies" myString = "das" myInt = 5 myInt = 15
(Was könnte einfacher sein.)
Sieht für mich wie das wäre der einfachste Weg, dies zu tun.
(Und es scheint zu funktionieren. Aber ist es wirklich richtig?)
Nicht alloc Speicher für meine NSMutableArray zunächst. Keine re-alloc Speicher wiederholt. (Wenn ich die array-Werte.) Nicht loslassen, immer wieder. (Bevor ich die array-Werte.) Nicht loslassen, wenn ich das Programm beenden. Aber: Bitte immer daran denken, BEHALTEN, wenn ich zunächst zuordnen (und immer wieder neu zuordnen) neue Werte zu meinem anArray variable.
Sind Sie nicht geladen, das array mit
anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
Stattdessen ersetzen Sie es mit einer neuen Instanz, und noch schlimmer: mit einer Instanz, deren
Referenz ist eigentlich im Besitz von einigen Person, die Sie nicht kontrollieren
Wow. So konnte ich 20 arrays... alle aufgerufen, die den gleichen Namen: anArray... und Sie würden alle anders? (Es gibt keine solche Sache wie ein GLOBALES array?)
etc. Um zu löschen Sie die alten Werte, die Methode removeAllObject kann nützlich sein.
Es gibt auch mutation Methoden, die verwendet werden können, um mehrere Werte auf einmal.
Also... zuerst habe ich auf "entfernen Sie alle Objekte"... und dann kann ich rufen EINE Methode es erneut hinzufügen alle meine neuen Werte.
anArray = [[NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil] retain];
statt der alloc/init-Sequenz.
Wow. Ich dachte, nichts könnte gespeichert in einem array, ohne alloc ' Ing für ihn den Platz.
Wenn Sie wirklich wollen, zu ersetzen, das gesamte array, möchten Sie vielleicht zu prüfen,
mit Eigenschaften
Wie soll ich das tun mit Eigenschaften?
Was wäre der richtige Weg, so etwas zu tun:
> anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil]; > anArray = [NSMutableArray arrayWithObjects:@"four", @"fünf", @"sechs", nil];
Genau wie ich tun würde:
x = 12; x = 24;
Wow. Ich WIRKLICH haben völlig missverstehen alles, was über strings, arrays und Speicher.
Ich dachte, die "einfach Weg" wurde alloc EINMAL... nutzen Sie die mutable-array... ändern Sie es so viel wie Sie wollen... und Kostenlose EINMAL.
Das problem dabei ist, dass dieses neue array nicht beibehalten,
Ich würde denken, dass das alte array wäre gegangen... und die neue Anordnung verwendet werden könnte.
(Aber ich denke mal nicht.)
Weiter, du hast ein Speicherleck, weil Sie nie befreit das original-array.
Ich dachte das alte array nicht angenommen, befreit zu werden... ich bin nicht fertig mit ihm... ich wünschte nur, es ÄNDERN zu enthalten meine neuen Werte. (Aber ich denke mal nicht.)
aber ist die Verwendung von [anArray release];
Dachte ich mir, das würde dazu führen, mich um den Speicher freizugeben, habe ich zugewiesen... (aber ich denke mal nicht)... und dann müsste ich wieder alloc mehr Speicher. (Aber ich denke mal nicht.)
anArray = [[NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil] retain];
Also ich habe für "behalten" es... also es verschwindet nicht unter mir?
(Nicht sicher, warum es würde. Bis ich sagen, dass es... in meinem letzten dealloc nennen.)
Andere, wohl richtigere Weg, um es zu beheben wäre, um die addObject: oder
addObjectsFromArray: NSMutableArray Methoden statt ständig neue arrays.
Ich nur erstellen möchten EINE array... und es einfach verwenden, wie ich will.
Ich will nie HINZUFÜGEN auf das array. Ich möchte, um es an meine neuen Werte.
Ich wünschte, ich könnte Ihnen mehr als ein up-vote - ich habe exakt die gleichen Probleme - Objective-C ist über counter-intuitive.
InformationsquelleAutor Bonnie | 2010-02-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie nicht laden Sie Ihr array mit
Statt, Sie ersetzen es mit einer neuen Instanz, und noch schlimmer: mit einem Beispiel, dessen Referenz ist eigentlich im Besitz von einigen Person, die Sie nicht kontrollieren können (höchstwahrscheinlich, ein
NSAutoreleasePool
.) Die Referenz, die Sie richtig in Besitz, die eine erstellt durchist verloren und wird geleckt.
Anstatt Sie zu ersetzen die gesamte array-Referenz, mutieren die, die Sie haben zu Ihrer Verfügung bereits, mit zum Beispiel
addObject:
wieetc. Um zu löschen Sie die alten Werte, die Methode
removeAllObject
kann nützlich sein. Es gibt auch mutation Methoden, die verwendet werden können, um mehrere Werte auf einmal.Alternativ können Sie zuweisen, das array mit den Bau-Methode, die Sie bereits verwenden, aber seien Sie vorsichtig, es zu binden. In
viewDidLoad
tunstatt der
alloc
/init
Sequenz.Wenn Sie wirklich wollen, zu ersetzen, das gesamte array, möchten Sie vielleicht zu prüfen, mit Eigenschaften zu tun, anstatt die Referenz-Zählung manuell.
InformationsquelleAutor Dirk
Das problem ist
anArray = [NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil];
Dies ersetzt das array, das Sie ursprünglich geschaffen wurde. Das problem dabei ist, dass dieses neue array nicht gespeichert, so dass Sie es verlieren, sobald die Methode zurückkehrt. Weitere, Sie haben einen memory-leak, weil Sie nie befreit das original-array.Gibt es mehrere Möglichkeiten, um dieses Problem zu lösen, aber eine ist
[anArray release]; anArray = [[NSMutableArray arrayWithObjects:@"one", @"two", @"three", nil] retain];
statt.Andere, wohl richtigere Weg, um es zu beheben wäre, um die
addObject:
oderaddObjectsFromArray:
NSMutableArray
Methoden statt ständig neue arrays.InformationsquelleAutor David Kanarek
Denken Sie daran, diese einfache Speicher-Regel: lassen Sie nur die Objekte, die Sie besitzen. Sie eigenen Objekte nur, wenn Sie Sie erstellen mithilfe von:
init
(diese Methode erstellt ein neues Objekt mit einem retain count von 1)new
(diese Methode ist identisch mit alloc und init)copy
(diese Methode erstellt ein neues Objekt mit einem retain count von 1 und mit dem Inhalt der Empfänger der Methode)retain
(diese Methode erhöht den retain count-1) -System
dealloc
ates automatisch Objekte mit einem retain count von null. Sie müssenrelease
jedes Objekt, das Sie besitzen, nachdem Sie fertig sind mit ihm. Wenn Sierelease
zu früh, erhalten Sie eine gefährliche situation. Wenn Sie nichtrelease
Ihr Objekt, wenn Sie damit fertig sind, erhalten Sie ein Leck.Einen Zeiger ist ein spezielles Objekt, das bezieht sich auf ein Objekt im Speicher. Es ist im Grunde ein Speicher-Adresse (und einige andere Daten). Wenn Sie wollen, ein Objekt zu verwenden, müssen Sie
alloc
aß Speicher und danninit
ialize. Weisen Sie (durch Benutzung der=
- Zeichen) auf einen Zeiger.string
hat jetzt einen retain count von eins. Aber daNSString
ist ein immutable-Objekt, es kann nicht geändert werden, nachdem die Initialisierung. Ein Weg zu weisenstring
Wert ist, indem Sie es während der Initialisierung.Wenn Sie Sie brauchen, um
string
regelmäßig verwenden, können Sie eine Klasse, die ist veränderlich:NSMutableString
. Aber dennoch, der einzige Weg, Sie zu ändern, ist in einer Mitteilung.Nur der Hinweis, der folgende code wird falsch und führt zu einem Speicherverlust.
In der ersten Zeile
string
zugeordnet ist, um ein neu erstelltes Objekt. In der zweitenstring
ist zugeordnet zu einer anderen Zeichenfolge. Sie verlieren die Referenz auf das neu erstellte Objekt und Sie erhalten ein Leck: Sie können nicht ein Objekt freigeben, die Sie nicht haben, einen Verweis auf.Erhalten Sie nicht ein problem, wenn Sie dies tun mit ganzen zahlen (
int
- Typ), weil es eine "native" - Objekt. Die Objective-C Runtime ordnet diese Datentypen direkt mit Ihrem Wert, nicht ein Zeiger.Hinweis 1. Vergessen Sie nicht, immer zu sagen, die Laufzeit, welche Art Sie den Mauszeiger. Wenn Sie verwenden möchten
string
zu können, definieren Sie es zuerst in Ihrem Kopf (bei den öffentlichen) oder die Umsetzung (wenn Sie es wollen, versteckt von anderen Methoden). Dann können Sie die Namen frei.Dem Stern erzählt die Laufzeit es ist ein Zeiger. Für native Typen, da ist kein Zeiger, also bekommen Sie diese.
Note 2. Arrays (und Wörterbücher, etc.) Verhalten sich alle wie
NSString
, dass Sie beide unveränderlichen und veränderlichen Varianten.Anmerkung 3. Die meisten Klassen haben spezielle Methoden, reservieren, initialisieren und autorelease alle auf einmal.
Einen autoreleased-Objekt nicht benötigen manuelle
release
wie das systemrelease
es für Sie nach einer Weile. Es ist sehr praktisch in Situationen, in denen Sie ein Objekt nur für die Dauer der Methode oder zwischen Methoden, die nicht als permanenter Teil des Objekts. Wenn Sieautorelease
einige Objekt auf dem Haupt-thread (in einer app mit GUI), es wirdrelease
d wenn die Ereignis-Schleife beendet die aktuelle Schleife (es endet, wenn ein Ereignis verarbeitet wird). Lesen Sie mehr über Autorelease-Pools in den Apple docs.Ich hoffe, dass ich allen helfen, die sich nicht gut verstehen, was Zeiger sind. Ich selbst Probleme hatte, für ein paar Monate, bis ich experimentierte stark. 🙂
Wenn Sie ARC (das ist der Standard in Xcode), die Sie nie verwenden
release
insgesamt. 😉InformationsquelleAutor