@property conserva, assegna, copia, non anatomico in Objective-C

Come qualcuno che è nuovo a Objective-C qualcuno può darmi una panoramica del mantenimento, assegnare, copiare e tutti gli altri mi manca, che seguono la direttiva @property? Cosa stanno facendo e perché dovrei usarne uno rispetto all’altro?

L’articolo collegato a MrMage non funziona più. Quindi, ecco quello che ho imparato nella mia (molto) breve codifica in Objective-C:

non atomico vs. atomico – “atomico” è l’impostazione predefinita. Usa sempre “nonatomico”. Non so perché, ma il libro che ho letto dice che “raramente è una ragione” per usare “atomico”. (A proposito: il libro che ho letto è il libro “Programmazione iOS” di BNR).

readwrite vs. readonly – “readwrite” è l’impostazione predefinita. Quando hai @sinteso, verranno creati per te getter e setter. Se si utilizza “readonly”, non verrà creato alcun setter. Usalo per un valore che non vuoi mai cambiare dopo l’istanziazione dell’object.

conservare contro copia e assegnare

  • “assegna” è l’impostazione predefinita. Nel setter creato da @synthesize, il valore verrà semplicemente assegnato all’attributo. La mia comprensione è che “assegna” dovrebbe essere usato per attributi non puntatore.
  • “retain” è necessario quando l’attributo è un puntatore a un object. Il setter generato da @synthesize manterrà (noto anche come conteggio di mantenimento) l’object. Avrai bisogno di rilasciare l’object quando hai finito con esso.
  • “copia” è necessario quando l’object è mutabile. Usalo se hai bisogno del valore dell’object così com’è in questo momento, e non vuoi che quel valore rifletta le modifiche apportate da altri proprietari dell’object. Avrai bisogno di rilasciare l’object quando hai finito con esso perché stai mantenendo la copia.

Prima di conoscere gli attributi di @property, dovresti sapere a cosa serve @property.

  • @property offre un modo per definire le informazioni che una class intende incapsulare. Se dichiari un object / variabile usando @property , quell’object / variabile sarà accessibile ad altre classi che importano la sua class.

  • Se dichiari un object usando @property nel file di intestazione, devi sintetizzarlo usando @synthesize nel file di implementazione. Questo rende l’object conforms a KVC . Per impostazione predefinita, il compilatore sintetizza i metodi di accesso per questo object.

  • i metodi di accesso sono: setter e getter.

Esempio: .h

 @interface XYZClass : NSObject @property (nonatomic, retain) NSString *name; @end 

.m

 @implementation XYZClass @synthesize name; @end 

Ora il compilatore sintetizzerà i metodi di accesso per il nome .

 XYZClass *obj=[[XYZClass alloc]init]; NSString *name1=[obj name]; // get 'name' [obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method 
  • Elenco di attributi di @property

    atomico, nonatomico, conservare, copiare, readonly, readwrite, assign, strong, getter = method, setter = method, unsafe_unretained

  • atomico è il comportamento predefinito. Se un object viene dichiarato atomico, diventa sicuro per i thread. Mezzi thread-safe, in un momento solo un thread di una particolare istanza di quella class può avere il controllo su quell’object.

Se il thread sta eseguendo il metodo getter, l’altro thread non può eseguire il metodo setter su quell’object. È lento

 @property NSString *name; //by default atomic` @property (atomic)NSString *name; // explicitly declared atomic` 
  • nonatomico non è thread-safe. È ansible utilizzare l’attributo della proprietà nonatomico per specificare che gli accessori sintetizzati semplicemente impostano o restituiscono un valore direttamente, senza garanzie su ciò che accade se si accede allo stesso valore contemporaneamente da diversi thread.

Per questo motivo, è più veloce accedere a una proprietà nonatomica che a una atomica.

 @property (nonatomic)NSString *name; 
  • retain è richiesto quando l’attributo è un puntatore a un object.

Il metodo setter aumenterà il conteggio dei ritardi dell’object, in modo che occupi memoria nel pool autorelease.

 @property (retain)NSString *name; 
  • copia Se usi la copia, non puoi usare retain. L’utilizzo dell’istanza di copia della class conterrà la propria copia.

Anche se viene impostata una stringa mutabile e successivamente modificata, l’istanza acquisisce il valore che ha nel momento in cui è impostata. Nessun metodo setter e getter sarà sintetizzato.

 @property (copy) NSString *name; 

adesso,

 NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"]; xyzObj.name = nameString; [nameString appendString:@"Pizza"]; 

il nome rimarrà inalterato.

  • readonly Se non si desidera consentire la modifica della proprietà tramite il metodo setter, è ansible dichiarare la proprietà in sola lettura.

Il compilatore genererà un getter, ma non un setter.

 @property (readonly) NSString *name; 
  • readwrite è il comportamento predefinito. Non è necessario specificare esplicitamente l’attributo readwrite.

È opposto di readonly.

 @property (readwrite) NSString *name; 
  • Assegnare genererà un setter che assegna direttamente il valore alla variabile di istanza, piuttosto che copiarlo o mantenerlo. Questo è il migliore per i tipi primitivi come NSInteger e CGFloat o gli oggetti che non possiedi direttamente, come i delegati.

Tenere presente che la conservazione e l’assegnazione sono fondamentalmente intercambiabili quando la garbage collection è abilitata.

 @property (assign) NSInteger year; 
  • forte è un sostituto per conservare.

Viene fornito con ARC.

 @property (nonatomic, strong) AVPlayer *player; 
  • getter = method Se si desidera utilizzare un nome diverso per un metodo getter, è ansible specificare un nome personalizzato aggiungendo attributi alla proprietà.

Nel caso di proprietà booleane (proprietà che hanno un valore YES o NO), è consuetudine che il metodo getter inizi con la parola “is”

 @property (getter=isFinished) BOOL finished; 
  • setter = method Se si desidera utilizzare un nome diverso per un metodo setter, è ansible specificare un nome personalizzato aggiungendo attributi alla proprietà.

Il metodo dovrebbe terminare con due punti.

 @property(setter = boolBool:) BOOL finished; 
  • unsafe_unretained Esistono alcune classi in Cocoa e Cocoa Touch che non supportano ancora riferimenti deboli, il che significa che non è ansible dichiarare una proprietà debole o una variabile locale debole per tenerne traccia. Queste classi includono NSTextView, NSFont e NSColorSpace, ecc. Se è necessario utilizzare un riferimento debole a una di queste classi, è necessario utilizzare un riferimento non sicuro.

Un riferimento non sicuro è simile a un riferimento debole in quanto non mantiene attivo il relativo object correlato, ma non verrà impostato su zero se l’object di destinazione è deallocato.

 @property (unsafe_unretained) NSObject *unsafeProperty; 

Se devi specificare più attributi, includili semplicemente come un elenco separato da virgole, in questo modo:

 @property (readonly, getter=isFinished) BOOL finished; 

Dopo aver letto molti articoli ho deciso di mettere insieme tutte le informazioni sugli attributi:

  1. atomico // predefinito
  2. nonatomic
  3. strong = retain // default
  4. weak = unsafe_unretained
  5. conservare
  6. assegna // default
  7. unsafe_unretained
  8. copia
  9. sola lettura
  10. readwrite // default

Di seguito è riportato un collegamento all’articolo dettagliato in cui è ansible trovare questi attributi.

Mille grazie a tutte le persone che danno le migliori risposte qui !!

Attributi di proprietà variabili o modificatori in iOS

Ecco la descrizione del campione dall’articolo

  1. atomico -Atomico significa che solo un thread accede alla variabile (tipo statico). -Atomic è thread-safe. -ma è lento nelle prestazioni -atomico è comportamento predefinito -Accessori atomici in un ambiente non garbage collocato (cioè quando si usa retain / release / autorelease) userà un lock per assicurarsi che un altro thread non interferisca con l’impostazione corretta / ottenendo del valore. -It non è in realtà una parola chiave.

Esempio :

 @property (retain) NSString *name; @synthesize name; 
  1. nonatomico -Nonatomico significa accesso multiplo alla variabile (tipo dinamico). -Nonatomico non è sicuro. -ma è veloce nelle prestazioni -Nonatomico NON è un comportamento predefinito, dobbiamo aggiungere una parola chiave nonatomica nell’attributo della proprietà. -it può comportare un comportamento imprevisto, quando due processi diversi (thread) accedono alla stessa variabile allo stesso tempo.

Esempio:

 @property (nonatomic, retain) NSString *name; @synthesize name; 

Spiegare:

Supponiamo che ci sia una proprietà di stringa atomica chiamata “nome”, e se chiami [self setName: @ “A”] dal thread A, chiama [self setName: @ “B”] dal thread B e chiama [self name] da thread C, quindi tutte le operazioni su thread diversi verranno eseguite in serie, il che significa che se un thread sta eseguendo setter o getter, allora altri thread attenderanno. Questo rende la proprietà “nome” in lettura / scrittura sicura, ma se un altro thread D chiama [nome release] contemporaneamente, questa operazione potrebbe causare un arresto anomalo perché non è presente alcuna chiamata setter / getter. Il che significa che un object è in lettura / scrittura sicuro (ATOMIC) ma non thread safe poiché un altro thread può inviare contemporaneamente qualsiasi tipo di messaggio all’object. Lo sviluppatore dovrebbe garantire la sicurezza del thread per tali oggetti.

Se il “nome” della proprietà era nonatomico, tutti i thread nell’esempio precedente – A, B, C e D verranno eseguiti simultaneamente producendo risultati imprevedibili. In caso di atomico, uno di A, B o C verrà eseguito per primo ma D può ancora essere eseguito in parallelo.

  1. forte (iOS4 = conserva) – dice “mantieni questo 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 conservare” – Si utilizza forte solo se è necessario conservare l’object. -Per default tutte le variabili di istanza e le variabili locali sono potenti puntatori. -Si generalmente usiamo forti per UIViewControllers (i genitori degli elementi dell’interfaccia utente) -strong è usato con ARC e fondamentalmente ti aiuta, non dovendo preoccuparti del numero di ritenzione di un object. ARC lo rilascia automaticamente quando hai finito. Utilizzare la parola chiave strong significa che possiedi l’object.

Esempio:

 @property (strong, nonatomic) ViewController *viewController; @synthesize viewController; 
  1. debole (iOS4 = unsafe_unretained) -it dice “mantieni questo finché qualcuno lo punta con forza” -la stessa cosa di assegnare, non conservare o rilasciare -Un riferimento “debole” è un riferimento che non si mantiene. -In genere usiamo debole per IBOutlet (UIViewController’s Childs). Questo funziona perché l’object figlio deve esistere solo se l’object padre lo fa. -un riferimento debole è un riferimento che non protegge l’object di riferimento dalla raccolta da un garbage collector. -La debolezza è essenzialmente assegnata, una proprietà non trattenuta. Tranne il caso in cui l’object viene deallocato, il puntatore debole viene automaticamente impostato su zero

Esempio :

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

Spiegazione forte e debole, grazie a BJ Homer :

Immagina che il nostro object sia un cane e che il cane voglia scappare (essere disallocato). Puntatori forti sono come un guinzaglio sul cane. Finché hai il guinzaglio attaccato al cane, il cane non scapperà. Se cinque persone attaccano il loro guinzaglio a un cane, (cinque punti forti a un object), il cane non scapperà finché tutti e cinque i guinzagli non saranno staccati. Puntatori deboli, d’altra parte, sono come bambini piccoli che puntano il cane e dicono “Guarda! Un cane!” Finché il cane è ancora al guinzaglio, i bambini piccoli possono ancora vedere il cane, e continueranno a indicarlo. Non appena tutti i guinzagli sono staccati, però, il cane scappa non importa quanti bambini piccoli lo stanno indicando. Non appena l’ultimo puntatore forte (guinzaglio) non punta più su un object, l’object sarà deallocato e tutti i puntatori deboli saranno azzerati. Quando usiamo debole? L’unica volta che si vorrebbe usare debole, è se si volesse evitare i cicli di conservazione (ad esempio il genitore conserva il figlio e il figlio conserva il genitore, quindi nessuno dei due viene mai rilasciato).

  1. retain = strong -it viene mantenuto, il vecchio valore viene rilasciato ed è assegnato -retain specifica che il nuovo valore deve essere inviato -retain sull’assegnazione e il vecchio valore inviato -release -retain è lo stesso di strong. -apple dice che se si scrive, verrà convertito automaticamente / funzionerà come solo forte. -metodi come “alloc” includono un “retain” implicito

Esempio:

 @property (nonatomic, retain) NSString *name; @synthesize name; 
  1. assign -assign è l’impostazione predefinita e esegue semplicemente un’assegnazione di variabile -assign è un attributo di proprietà che dice al compilatore come sintetizzare l’implementazione del setter della proprietà -Io vorrei assegnare per le proprietà primitive C e debole per i riferimenti deboli agli oggetti Objective-C.

Esempio:

 @property (nonatomic, assign) NSString *address; @synthesize address; 
  1. unsafe_unretained

    -unsafe_unretained è un qualificatore di proprietà che indica a ARC come inserire le chiamate di mantenimento / rilascio -unsafe_unretained è la versione ARC di assign.

Esempio:

 @property (nonatomic, unsafe_unretained) NSString *nickName; @synthesize nickName; 
  1. copy -copy è richiesto quando l’object è mutabile. -copy specifica che il nuovo valore deve essere inviato -copia sull’assegnazione e il vecchio valore inviato -release. -copy è come mantenere restituisce un object che devi rilasciare esplicitamente (ad esempio, in dealloc) in ambienti non-garbage collection. -se usi la copia, devi ancora rilasciarlo in dealloc. -Utilizzare questo se avete bisogno del valore dell’object così com’è in questo momento, e non volete che quel valore rifletta le modifiche apportate da altri proprietari dell’object. Avrai bisogno di rilasciare l’object quando hai finito con esso perché stai mantenendo la copia.

Esempio:

 @property (nonatomic, copy) NSArray *myArray; @synthesize myArray; 

La proprietà Atomic è accessibile solo da un thread alla volta. È thread-safe . Il valore predefinito è atomico. Si prega di notare che non vi è alcuna parola chiave atomica

Nonatomico significa che più thread possono accedere all’elemento. È un thread non sicuro

Quindi si dovrebbe prestare molta attenzione durante l’utilizzo di atomico. Come influisce sulle prestazioni del codice