Ziel C - Zuweisen, Kopieren, Beibehalten


83

Ich bin neu in Ziel C. Ich habe Grundkenntnisse in C, einschließlich des Konzepts der Zeiger. Ich habe zwei grundlegende Fragen:

  1. Kann jemand den Unterschied zwischen Zuweisen, Kopieren und Beibehalten mit einer Analogie erklären?
  2. Wie behandeln Sie eine Funktion, die eine Zeigervariable zurückgibt, und wie führen Sie Messaging über einen Rückgabezeiger durch?

Antworten:


126

Aktualisierte Antwort für geänderte Dokumentation

Die Informationen sind jetzt auf mehrere Handbücher in der Dokumentation verteilt. Hier ist eine Liste der erforderlichen Lektüre:

Die Antwort auf diese Frage hängt jetzt ganz davon ab, ob Sie eine ARC-verwaltete Anwendung verwenden (die moderne Standardeinstellung für neue Projekte) oder die manuelle Speicherverwaltung erzwingen.

Zuweisen vs. Schwach - Verwenden Sie Zuweisen , um den Zeiger einer Eigenschaft auf die Adresse des Objekts zu setzen, ohne es beizubehalten oder auf andere Weise zu kuratieren. Verwenden Sie schwach , damit die Eigenschaft automatisch auf Null verweist, wenn das ihr zugewiesene Objekt freigegeben wird. In den meisten Fällen möchten Sie schwach verwenden, damit Sie nicht versuchen, auf ein freigegebenes Objekt zuzugreifen (illegaler Zugriff auf eine Speicheradresse - " EXC_BAD_ACCESS"), wenn Sie keine ordnungsgemäße Bereinigung durchführen.

Beibehalten vs. Kopieren - Deklarierte Eigenschaften verwenden standardmäßig Beibehalten (Sie können sie also einfach ganz weglassen) und verwalten den Referenzzähler des Objekts automatisch, unabhängig davon, ob der Eigenschaft ein anderes Objekt zugewiesen oder auf Null gesetzt ist. Verwenden Sie copy , um dem neu zugewiesenen Objekt automatisch eine -copyNachricht zu senden (die eine Kopie des übergebenen Objekts erstellt und diese Kopie stattdessen der Eigenschaft zuweist - nützlich (sogar erforderlich) in einigen Situationen, in denen das zugewiesene Objekt nach dem Festlegen als geändert werden kann eine Eigenschaft eines anderen Objekts (was bedeuten würde, dass Modifikation / Mutation auch für die Eigenschaft gelten würde).


2
Vielen Dank, Alter. Ich habe die Grundlagen von Apple Dev zu meiner aktuellen Entwicklung gelesen. Es ist schwierig, Speicher zu verwalten. "Absturz in objc_msgSend ()" Also habe ich nur daran gedacht, mein Verständnis der Eigenschaften zu überarbeiten. stackoverflow.com/questions/4506205/…
Sabha B

2
Nur ein Kopf hoch, der Link in die Antwort führt zu einer generischen "Seite nicht gefunden" auf der Apfel-Website. Dann wird zur "Mac Developer Library" weitergeleitet. Diese SO-Antwort enthält nützliche Informationen: stackoverflow.com/questions/2255861/…
hippeelee

1
Es ist schwierig zu aktualisieren, da sich die Dokumentation geändert hat und sich nicht mehr an einem geeigneten Ort befindet. Feedback an das Apple Doc-Team gesendet.
Joshua Nozzi

33

Das Programmierhandbuch zur Speicherverwaltung aus der iOS-Referenzbibliothek enthält Grundlagen zum Zuweisen, Kopieren und Aufbewahren mit Analogien und Beispielen.

Kopieren Erstellt eine Kopie eines Objekts und gibt sie mit der Anzahl von 1 zurück. Wenn Sie ein Objekt kopieren, besitzen Sie die Kopie. Dies gilt für alle Methoden, die das Wort copy enthalten, wobei sich "copy" auf das zurückgegebene Objekt bezieht.

Beibehalten Erhöht die Anzahl der Beibehaltungen eines Objekts um 1. Übernimmt das Eigentum an einem Objekt.

release Verringert die Anzahl der Aufbewahrungen eines Objekts um 1. Gibt das Eigentum an einem Objekt auf.


Vielen Dank für Ihre Antwort. Könnten Sie bitte erklären, 1.ClassA hat eine Eigenschaft namens - (Klasse B *) functionName; 2.ClassB have method - (void) setHeight; 3.ClassC-Schnittstelle Ich habe ClassA * tempA als beibehalten deklariert. 4. Klasse C Implementierung im Konstruktor Ich habe diese Anweisung ClassB * tempB = tempA.functionName; 5.Wenn ich versuche, in der nächsten Zeile der TempB-Initialisierung eine Nachricht (tempB. SetHeight;) zu senden, funktioniert mein Programm einwandfrei.
Sabha B

6.Die gleiche Anweisung (tempB. SetHeight;) in eine Funktion eingeben und dieselbe Funktion aufrufen, wird mein Programm in objc_msgSend () abgestürzt.
Sabha B

8
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"First",@"Second", nil];
NSMutableArray *copiedArray = [array mutableCopy];
NSMutableArray *retainedArray = [array retain];

[retainedArray addObject:@"Retained Third"];
[copiedArray addObject:@"Copied Third"];

NSLog(@"array = %@",array);
NSLog(@"Retained Array = %@",retainedArray);
NSLog(@"Copied Array = %@",copiedArray);

array = (
    First,
    Second,
    "Retained Third"
)
Retained Array = (
    First,
    Second,
    "Retained Third"
)
Copied Array = (
    First,
    Second,
    "Copied Third"
)

2
Eine umgebende Erklärung würde Ihre Antwort ernsthaft verbessern.
zx485

4
  1. zuordnen

    • Zuweisen ist ein Standardeigenschaftsattribut
    • Zuweisen ist ein Eigenschaftsattribut, das dem Compiler mitteilt, wie die Setter-Implementierung der Eigenschaft synthetisiert werden soll
  2. Kopieren:

    • Eine Kopie ist erforderlich, wenn das Objekt veränderbar ist
    • copy gibt ein Objekt zurück, das Sie explizit freigeben müssen (z. B. in Dealloc), in Umgebungen, in denen kein Müll gesammelt wurde
    • Sie müssen das Objekt freigeben, wenn Sie damit fertig sind, da Sie die Kopie behalten
  3. behalten:

    • Gibt an, dass der neue Wert bei der Zuweisung "-retain" und der alte Wert "-release" gesendet werden soll.
    • Wenn Sie Retain schreiben, funktioniert es automatisch wie stark
    • Methoden wie "Zuweisen" beinhalten ein implizites "Beibehalten"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.