Attributi di setter di proprietà deboli e forti in Objective-C


94

Qual è la differenza tra gli attributi di impostazione della proprietà debole e forte in Objective-C?

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

Qual è l'impatto e il vantaggio?

Ho sentito che debole non è disponibile su iOS 4 e dobbiamo usare assign.

È debole simile da assegnare?


Risposte:


102

Hai ARC attivato o disattivato per un particolare file. Se è attivo non puoi usare retain release autoreleaseecc ... Invece lo usi strong weakper le proprietà o __strong __weak per le variabili (il valore predefinito è __strong). Strong è l'equivalente da mantenere, tuttavia ARC gestirà il rilascio per te.

L'unico momento in cui vorresti usare deboli, è se volessi evitare i cicli di conservazione (ad esempio, il genitore mantiene il bambino e il bambino mantiene il genitore in modo che nessuno dei due venga mai rilasciato).

La parte "ponte senza pedaggio" (casting da NSa CF) è un po 'complicata. Devi ancora gestire manualmente CFRelease()e CFRetain()per gli oggetti CF. Quando li converti di nuovo in oggetti NS, devi dire al compilatore del conteggio di conservazione in modo che sappia cosa hai fatto.

È tutto qui .


119

Ecco le informazioni su ciò che so sulle proprietà delle variabili

  1. atomic // predefinito
  2. non atomico
  3. forte = conserva // predefinito
  4. debole
  5. trattenere
  6. assegna // predefinito
  7. unsafe_unretained
  8. copia
  9. sola lettura
  10. readwrite // predefinito

quindi di seguito è riportato il collegamento dettagliato dell'articolo in cui puoi trovare tutti gli attributi sopra menzionati, che ti aiuteranno in modo provocatorio. Mille grazie a tutte le persone che qui danno le migliori risposte !!

Attributi delle proprietà variabili o modificatori in iOS

01. strong (iOS4 = keep ) - dice "tienilo nell'heap fino a quando non lo indico più" - in altre parole "sono il proprietario, non puoi deallocarlo prima di mirare bene con quello stesso di keep "- Usi forte solo se hai bisogno di trattenere l'oggetto. - Per impostazione predefinita, tutte le variabili di istanza e le variabili locali sono puntatori forti. - Generalmente usiamo strong per UIViewControllers (i genitori degli elementi dell'interfaccia utente) - strong viene utilizzato con ARC e fondamentalmente ti aiuta, non dovendo preoccuparti del conteggio di conservazione di un oggetto. ARC lo rilascia automaticamente quando hai finito. Usare la parola chiave forte significa che sei il proprietario dell'oggetto.

Esempio:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. weak (iOS4 = unsafe_unretained) - dice "tienilo finché qualcun altro lo indica fortemente" - la stessa cosa di assign, no hold o release - Un riferimento "debole" è un riferimento che non mantieni. - Generalmente usiamo deboli per IBOutlet (UIViewController's Childs). Questo funziona perché l'oggetto figlio deve esistere solo finché esiste l'oggetto genitore. - un riferimento debole è un riferimento che non protegge l'oggetto referenziato dalla raccolta da parte di un garbage collector. - Debole è essenzialmente assegnare, una proprietà non mantenuta. Tranne quando l'oggetto viene deallocato, il puntatore debole viene automaticamente impostato a zero

Esempio :

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

@synthesize myButton;

Spiega : grazie a BJ Homer

Immagina che il nostro oggetto sia un cane e che il cane voglia scappare (essere deallocato). I puntatori forti sono come un guinzaglio per il cane. Finché hai il guinzaglio attaccato al cane, il cane non scapperà. Se cinque persone attaccano il guinzaglio a un cane, (cinque forti puntatori a un oggetto), il cane non scapperà finché tutti e cinque i guinzagli non saranno staccati. Gli indicatori deboli, d'altra parte, sono come bambini piccoli che indicano il cane e dicono "Guarda! Un cane!" Finché il cane è ancora al guinzaglio, i bambini piccoli possono ancora vedere il cane e lo indicheranno ancora. Non appena tutti i guinzagli vengono staccati, però, il cane scappa, non importa quanti bambini lo stiano indicando. Non appena l'ultimo puntatore forte (leash) non punta più a un oggetto, l'oggetto verrà deallocato e tutti i puntatori deboli verranno azzerati. Quando usiamo debole? L'unico momento in cui vorresti usare deboli, è se volessi evitare i cicli di conservazione (ad esempio, il genitore mantiene il bambino e il bambino mantiene il genitore in modo che nessuno dei due venga mai rilasciato).


1
Nella lista iniziale, non sono molto sicuro di cosa intendi per "predefinito". Hai entrambi strong=retaine assignetichettati come predefiniti, ma non può essere entrambi.
Slipp D. Thompson,

27
Mi è piaciuto il confronto con il cane al guinzaglio. Lo spiega abbastanza bene.
Jarrett Barnett

1
Buona spiegazione, sebbene iOS non utilizzi la garbage collection. ARC! = Garbage collection (!), Queste sono tecnologie diverse.

1
weak e unsafe_unretained sono diversi (il primo usa riferimenti deboli azzeramento, mentre il secondo fa squat)
wcochran

1
Sto solo imparando iOS, ma sembra che tu abbia smarrito il weake strongnei tuoi esempi. Non avrebbe più senso che un genitore abbia strongriferimenti ai suoi figli (come myButtonproprietà della UIViewControllerclasse che hai dimostrato di essere weak) e che i figli mantengano i weakriferimenti al loro genitore (come la viewControllerproprietà di una classe figlia che tu ' ho invece impostato su strong). Ad esempio, leggendo Matt Neuburg iOS 7 Programming Fundamentalsmostra che una classe che dichiara il proprio delegato come proprietà lo manterrà `debole, sembra giusto.
Bogdan Alexandru

2

Per richiamare le parti dei documenti a cui fa riferimento Robert che rispondono esplicitamente alle tue ultime due domande:

// 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;

Questo è indicato come un riferimento debole di azzeramento. È possibile creare riferimenti deboli che non annullino i riferimenti deboli utilizzando __unsafe_unretained, ma come suggerisce il nome, in genere non è consigliato.

Anche nei documenti:

Weak references are not supported in Mac OS X v10.6 and iOS 4.

1
Sì, è corretto, __unsafe_unretainedè la versione ARC di assign.
Robert

2

L'uso cristallino della proprietà DEBOLE è il seguente:

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;

1
Utilizzando debole sulle mie proprietà, ricevo un avviso che dice: "Il ricevitore debole potrebbe essere impostato in modo imprevedibile a zero". Ho visto altri post che per evitare questo avviso, devi creare un forte riferimento locale. E se questo è vero, che senso ha indebolire un immobile, se alla fine devo creare un riferimento forte?
arh

0

prendiamo un esempio per elaborare di più (le risposte sopra sono già ottime), che questo esempio aiuti un po 'di più

abbiamo due classi A e 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;
   }

il codice precedente genererà un ciclo di conservazione perché entrambi sono del tipo forte a --------> b ---------> a

quindi per evitarlo devi usare la proprietà week di uno di essi in modo che si riferisca settimanalmente all'oggetto e non aumenti il ​​conteggio dei riferimenti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.