Słabe i silne atrybuty ustawiające właściwości w Objective-C

94

Jaka jest różnica między słabym a silnym atrybutem ustawiającym właściwości w Objective-C?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Jaki jest wpływ i korzyści?

Słyszałem, że słaby nie jest dostępny na iOS 4 i musimy użyć przypisania.

Czy słaby jest podobny do przypisania?

kkurni
źródło

Odpowiedzi:

102

Możesz włączyć lub wyłączyć ARC dla określonego pliku. Jeśli jest włączona, nie możesz użyć retain release autoreleaseetc ... Zamiast tego używasz strong weakdla właściwości lub __strong __weak dla zmiennych (domyślnie __strong). Mocny to odpowiednik zachowania, jednak ARC zarządza wydaniem za Ciebie.

Jedyny przypadek, w którym chciałbyś użyć słabego, to gdybyś chciał uniknąć zachowania cykli (np. Rodzic zatrzymuje dziecko, a dziecko rodzica, więc żadne z nich nie jest nigdy zwolnione).

Część „darmowego mostu” (odlewanie od NSdo CF) jest trochę skomplikowana. Nadal musisz ręcznie zarządzać CFRelease()i CFRetain()dla obiektów CF. Kiedy konwertujesz je z powrotem na obiekty NS, musisz powiedzieć kompilatorowi o liczbie zachowań, aby wiedział, co zrobiłeś.

Wszystko jest tutaj .

Robert
źródło
119

Oto informacje, które wiem o właściwościach zmiennych

  1. atomowy // domyślny
  2. nieatomowy
  3. strong = retain // default
  4. słaby
  5. zachować
  6. przypisać // domyślne
  7. unsafe_unretained
  8. Kopiuj
  9. tylko czytać
  10. readwrite // default

więc poniżej znajduje się link do szczegółowego artykułu, w którym można znaleźć wyżej wymienione wszystkie atrybuty, które zdecydowanie Ci pomogą. Wielkie dzięki dla wszystkich ludzi, którzy udzielają tutaj najlepszych odpowiedzi !!

Zmienne atrybuty właściwości lub modyfikatory w iOS

01. strong (iOS4 = retain) - jest napisane „trzymaj to w stosie, dopóki nie wskażę tego więcej” - innymi słowy „Jestem właścicielem, nie możesz cofnąć przydziału, zanim wycelujesz dobrze z tym samym co zatrzymaj "- Używasz silnego tylko wtedy, gdy musisz zachować przedmiot. - Domyślnie wszystkie zmienne instancji i zmienne lokalne są silnymi wskaźnikami. - Generalnie używamy strong dla UIViewControllers (rodziców elementu UI) - strong jest używane z ARC i zasadniczo pomaga, ponieważ nie musisz martwić się o liczbę zatrzymań obiektu. ARC automatycznie zwalnia go za Ciebie, gdy skończysz z tym. Użycie słowa kluczowego strong oznacza, że ​​jesteś właścicielem obiektu.

Przykład:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. słaby (iOS4 = unsafe_unretained) - jest napisane „trzymaj to tak długo, jak ktoś inny mocno na to wskazuje” - to samo, co przypisuj, nie zachowaj ani nie zwolnij - „Słabe” odniesienie to odniesienie, którego nie zachowujesz. - Zwykle używamy słabego dla IBOutlets (UIViewController's Childs). Działa to, ponieważ obiekt potomny musi istnieć tylko tak długo, jak obiekt nadrzędny. - słabe odwołanie to odwołanie, które nie chroni obiektu, do którego się odwołujemy, przed zebraniem przez moduł odśmiecania pamięci. - Słabe jest w istocie przypisane, niezatrzymane. Z wyjątkiem sytuacji, w której obiekt jest zwalniany, słaby wskaźnik jest automatycznie ustawiany na zero

Przykład:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

Wyjaśnij : podziękowania dla BJ Homera

Wyobraź sobie, że naszym przedmiotem jest pies, który chce uciec (zostać zwolniony). Silne wskazówki są jak smycz na psie. Dopóki masz przypiętą smycz do psa, pies nie ucieknie. Jeśli pięć osób przypina smycz do jednego psa (pięć mocnych wskazówek do jednego przedmiotu), pies nie ucieknie, dopóki wszystkie pięć smyczy nie zostanie odczepione. Z drugiej strony słabe wskazówki są jak małe dzieci, które wskazują na psa i mówią „Patrz! Pies!”. Dopóki pies jest na smyczy, małe dzieci mogą go nadal widzieć i nadal będą na niego wskazywać. Jednak gdy tylko wszystkie smycze zostaną odpięte, pies ucieka bez względu na to, ile małych dzieci na niego wskazuje. Gdy tylko ostatni silny wskaźnik (smycz) nie będzie już wskazywał na obiekt, obiekt zostanie zwolniony, a wszystkie słabe wskaźniki zostaną wyzerowane. Kiedy używamy słabych? Jedyny przypadek, w którym chciałbyś użyć słabego, to gdybyś chciał uniknąć zachowania cykli (np. Rodzic zatrzymuje dziecko, a dziecko rodzica, więc żadne z nich nie jest nigdy zwolnione).

swiftBoy
źródło
1
Na wstępnej liście nie jestem do końca pewien, co masz na myśli mówiąc „domyślnie”. Masz oba strong=retaini assignoznaczone jako domyślne, ale nie może to być oba.
Slipp D. Thompson
27
Podobał mi się pies na smyczy. To całkiem dobrze wyjaśnia.
Jarrett Barnett
1
Dobre wyjaśnienie, chociaż iOS nie używa czyszczenia pamięci. ARC! = Wyrzucanie śmieci (!), To są różne technologie.
1
słabe i unsafe_unretained są różne (pierwsza używa zerowych słabych odniesień, podczas gdy druga robi przysiad)
wcochran
1
Uczę się tylko iOS, ale wygląda na to, że źle umieściłeś weaki strongw swoich przykładach. Czy nie byłoby bardziej sensowne, gdyby rodzic miał strongodniesienia do swoich dzieci (jako myButtonwłasność UIViewControllerklasy, którą pokazałeś weak) i że dzieci zachowują weakodniesienia do swojego rodzica (jak viewControllerwłasność klasy potomnej, którą ty? ve zamiast tego ustaw na strong). Na przykład, czytając Matta Neuburga, iOS 7 Programming Fundamentalspokazuje, że klasa, która deklaruje delegata jako własność, utrzyma ją w stanie „słabym, to wydaje się sprawiedliwe.
Bogdan Alexandru
2

Aby przywołać fragmenty dokumentów, do których odwołuje się Robert, a które bezpośrednio odpowiadają na twoje dwa ostatnie pytania:

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

Nazywa się to zerowym słabym odniesieniem. Możesz tworzyć słabe referencje, które nie zerują słabych referencji, używając __unsafe_unretained, ale jak sama nazwa wskazuje, generalnie nie jest to zalecane.

Również w dokumentach:

Weak references are not supported in Mac OS X v10.6 and iOS 4.
Rimsky
źródło
1
Tak, to prawda, __unsafe_unretainedjest to wersja ARC assign.
Robert
2

Krystalicznie jasne wykorzystanie właściwości WEAK jest następujące:

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;
Alen Alexander
źródło
1
Używając słabego na moich właściwościach, otrzymuję ostrzeżenie: „Słaby odbiornik może być nieprzewidywalnie ustawiony na zero”. Widziałem kilka innych postów, w których aby zapobiec temu ostrzeżeniu, musisz utworzyć lokalne silne odniesienie. A jeśli to prawda, jaki jest sens osłabiania właściwości, jeśli na końcu muszę stworzyć silne odniesienie?
arh
0

weźmy przykład, aby rozwinąć więcej (powyższe odpowiedzi są już świetne), niech ten przykład trochę bardziej pomoże

mamy dwie klasy A i B.

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

powyższy kod wygeneruje cykl utrzymania, ponieważ oba są silnym typem a --------> b ---------> a

aby tego uniknąć, musisz użyć właściwości week jednego z nich, aby co tydzień odnosił się do obiektu i nie zwiększał jego liczby referencji.

Anurag Bhakuni
źródło