Cel C - przypisz, skopiuj, zachowaj

84

Nie mam doświadczenia w Celu C. Mam podstawową wiedzę w języku C, w tym pojęcie wskaźników. Mam dwa podstawowe pytania:

  1. Czy ktoś może wyjaśnić różnicę między przypisywaniem, kopiowaniem i zachowywaniem za pomocą jakiejś analogii?
  2. Jak obsłużysz funkcję, która zwraca zmienną wskaźnikową i jak wykonujesz przesyłanie komunikatów za pomocą wskaźnika powrotu?
Sabha B
źródło

Odpowiedzi:

127

Zaktualizowana odpowiedź na zmienioną dokumentację

Informacje są teraz rozmieszczone w kilku przewodnikach w dokumentacji. Oto lista wymaganych lektur:

Odpowiedź na to pytanie zależy teraz całkowicie od tego, czy używasz aplikacji zarządzanej przez ARC (współczesne domyślne ustawienie dla nowych projektów), czy też wymuszasz ręczne zarządzanie pamięcią.

Assign vs. Weak - użyj przypisania, aby ustawić wskaźnik właściwości na adres obiektu bez zachowywania go lub w inny sposób kurowania; użyj słabego, aby właściwość wskazywała na zero automatycznie, jeśli przypisany do niej obiekt zostanie cofnięty. W większości przypadków będziesz chciał użyć słabego, aby nie próbować uzyskać dostępu do zwolnionego obiektu (nielegalny dostęp do adresu pamięci - „ EXC_BAD_ACCESS”), jeśli nie wykonasz właściwego czyszczenia.

Zachowaj a kopiuj - zadeklarowane właściwości używają zachowywania domyślnie (więc można je po prostu całkowicie pominąć) i automatycznie zarządzają liczbą odwołań do obiektu, niezależnie od tego, czy inny obiekt jest przypisany do właściwości, czy jest ustawiony na zero; Użyj kopii, aby automatycznie wysłać nowo przypisanemu obiektowi -copywiadomość (która utworzy kopię przekazanego obiektu i zamiast tego przypisze tę kopię do właściwości - przydatne (nawet wymagane) w niektórych sytuacjach, gdy przypisany obiekt może zostać zmodyfikowany po ustawieniu jako właściwość innego obiektu (co oznaczałoby, że modyfikacja / mutacja dotyczyłaby również tej właściwości).

Joshua Nozzi
źródło
2
Dzięki stary, przeczytałem podstawy z Apple Dev, dotyczące mojego obecnego rozwoju. Trudności z zarządzaniem pamięcią "zawiesiły się w objc_msgSend ()" Więc pomyślałem o zrewidowaniu mojego rozumienia właściwości. stackoverflow.com/questions/4506205/…
Sabha B,
2
Uwaga: odsyłacz do odpowiedzi prowadzi do ogólnego komunikatu „Nie znaleziono strony” w witrynie z jabłkami. Następnie przekierowuje do „Biblioteki programistów komputerów Mac”. Ta odpowiedź SO zawiera przydatne informacje: stackoverflow.com/questions/2255861/…
hippeelee
1
Trochę trudny do zaktualizowania, ponieważ dokumentacja się zmieniła i nie jest już w jednym wygodnym miejscu. Opinia wysłana do zespołu Apple ds. Dokumentacji.
Joshua Nozzi,
34

Programowanie Memory Management Guide z Biblioteki Reference iOS ma podstaw assign, skopiować i zachować z analogii i przykładów.

copy Tworzy kopię obiektu i zwraca ją z zachowaniem liczby 1. Jeśli kopiujesz obiekt, jesteś właścicielem kopii. Dotyczy to każdej metody zawierającej słowo copy, gdzie „kopia” odnosi się do zwracanego obiektu.

zachowaj Zwiększa liczbę zachowań obiektu o 1. Przejmuje własność obiektu.

release Zmniejsza liczbę zachowań obiektu o 1. Zrzecza się prawa własności do obiektu.

Larry Hipp
źródło
Dziękuję za odpowiedź. Czy mógłbyś wyjaśnić, że klasa 1.ClassA ma właściwość o nazwie - (klasa B *) nazwaFunkcji; 2. klasa B ma metodę - (void) setHeight; 3. Interfejs klasy C Zadeklarowałem ClassA * tempA jako retain. 4. implementacja klasy C w konstruktorze Mam tę instrukcję ClassB * tempB = tempA.functionName; 5.Kiedy próbuję wysłać wiadomość (tempB. SetHeight;) w następnej linii inicjalizacji tempB mój program działa poprawnie.
Sabha B
6. umieszczenie tej samej instrukcji (tempB. SetHeight;) w jakiejś funkcji i wywołanie tej samej funkcji mój program get Crashed w objc_msgSend ().
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"
)
srivas
źródło
2
Otaczające wyjaśnienie poważnie poprawiłoby twoją odpowiedź.
zx485
4
  1. przydzielać

    • przypisać jest domyślnym atrybutem właściwości
    • przypisać to atrybut właściwości, który informuje kompilator, jak zsyntetyzować implementację metody ustawiającej właściwość
  2. Kopiuj:

    • kopia jest wymagana, gdy obiekt jest zmienny
    • copy zwraca obiekt, który należy jawnie zwolnić (np. w dealloc) w środowiskach bez pamięci
    • musisz zwolnić obiekt po zakończeniu pracy, ponieważ zachowujesz kopię
  3. zachować:

    • określa, że ​​nowa wartość powinna zostać wysłana „-retain” przy przypisaniu, a stara wartość zostanie wysłana „-release”
    • jeśli napiszesz zachowaj, będzie działał jak silny
    • Metody takie jak „przydziel” obejmują niejawne „zatrzymanie”
Chen Rui
źródło