2009-11-02 11 views
13

mam uznającą właściwość NSString w klasie i objective-c narzeka, że:NSString nie 'assign', 'zachowują' lub 'copy' atrybut jest określony

NSString nie 'assign', ' Zachowaj atrybut "lub" Kopiuj "jest określony

Następnie niechcący informuje mnie, że" zamiast tego używane jest przypisanie ".

Czy ktoś może mi wyjaśnić różnicę pomiędzy przypisać, zachować i kopię w normalnych warunkach C zarządzania pamięcią funkcji?

Odpowiedz

29

Myślę, że zwraca uwagę na fakt, że jest używany assign, w przeciwieństwie do retain lub copy. Ponieważ obiekt NSString jest obiektem w środowisku zliczającym referencje (tzn. Bez zbierania śmieci), może być potencjalnie "niebezpieczny" (chyba że z założenia jest celowy).

Jednak różnica między assign, retain i copy są następujące:

  • przypisać: W setter dla nieruchomości, istnieje prosta Przypisanie zmiennej instancji do nowej wartości , np

    - (void)setString:(NSString*)newString 
    { 
        string = newString; 
    } 
    

    to może spowodować problemy, ponieważ przedmioty celem C użyciu liczenia odniesienia, a zatem, nie zachowując obiektu istnieje możliwość że ciąg może zostać zwolniony, gdy wciąż go używasz.

  • zachować: to zachowuje nowa wartość w setter. Na przykład:

    - (void)setString:(NSString*)newString 
    { 
        [newString retain]; 
        [string release]; 
        string = newString; 
    } 
    

    Jest to bezpieczniejsze, ponieważ wyraźnie stwierdzić, że chcesz zachować odniesienie do obiektu, a trzeba go zwolnić zanim zostanie ono zwalniane.

  • kopia: ta tworzy kopię napisu w setter metody:

    - (void)setString:(NSString*)newString 
    { 
        if(string!=newString) 
        { 
         [string release]; 
         string = [newString copy]; 
        } 
    } 
    

    ten jest często stosowany ze strun, ponieważ wykonanie kopii oryginalnego obiektu zapewnia, że ​​nie zmienia się podczas używasz tego.

10

Kakao używa licznika odniesienia do zarządzania pamięcią. Obiekty z liczbą odniesienia 0 są usuwane.

  • assign - nie robi nic, aby odwoływać się liczyć po prostu zaznacza swoją zmienną do danych
  • zachowują - zaznacza swoją zmienną do danych i dodaje 1 do liczenia odniesienia, dane są gwarantowane, aby tam być, gdy zmienna jest wciąż żywa
  • kopia - sprawia, że ​​kopia danych wskazuje zmienną na niego i sprawia, hrabia zachowują 1

Więcej szczegółów here przy dokumentacji własnej firmy Apple.

+1

zatrzymaj - __even if__ ktoś [deallocs] NSString, do którego się odwołujesz? Czy to działa tylko wtedy, gdy każdy użytkownik tej samej instancji [wypuszcza]? – bobobobo

+1

@obobobobo - powinieneś * nigdy * wywoływać 'dealloc' samodzielnie. Powinieneś zawsze używać 'release' lub' autorelease'. –

+0

Co powiedział Dave. Powodem, dla którego twoje dane są zagwarantowane, jest to, że zakładasz, że wszyscy inni używają wersji, obniżając licznik referencji tylko poprzez odniesienie. Jeśli inni ludzie lub ty sam, przepuścisz dealloc lub zwolnisz obiekt (nie przestrzegając zasad) twoje dane nie są gwarantowane! – bmalicoat

3

assign - ivar ustawia się wykonując proste zadanie. Realizacja:

- (void) setFoo:(NSString *)newFoo { 
    foo = newFoo; 
} 

retain - w Ivar wysyłana jest wiadomość zatrzymywania przed wykonaniem zadania. Realizacja:

- (void) setFoo:(NSString *)newFoo { 
    if (foo != newFoo) { 
    [foo release]; 
    foo = [newFoo retain]; 
    } 
} 

copy - w Ivar wysyłana jest wiadomość kopiowania przed wykonaniem zadania. Realizacja:

- (void) setFoo:(NSString *)newFoo { 
    if (foo != newFoo) { 
    [foo release]; 
    foo = [newFoo copy]; 
    } 
} 
+1

To nie są rzeczywiste implementacje, które kompilator @ syntetyzuje, ale demonstrują zachowanie z perspektywy zarządzania pamięcią (bez GC). –

+0

@Nikolai - tak, dzięki za wyjaśnienie. –

Powiązane problemy