uscita - ios 12 rilascio




Qual è la differenza tra gli attributi atomici e non anatomici? (18)

Che cosa significano atomic e non nonatomic nelle dichiarazioni di proprietà?

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

Qual è la differenza operativa tra questi tre?


atomico (predefinito)

Atomic è l'impostazione predefinita: se non si digita nulla, la proprietà è atomica. Una proprietà atomica è garantita che se si tenta di leggere da esso, si otterrà un valore valido. Non fornisce alcuna garanzia su quale potrebbe essere quel valore, ma recupererai buoni dati, non solo la memoria indesiderata. Ciò che questo ti permette di fare è se hai più thread o più processi che puntano a una singola variabile, un thread può leggere e un altro thread può scrivere. Se colpiscono allo stesso tempo, il thread del lettore è garantito per ottenere uno dei due valori: prima della modifica o dopo la modifica. Ciò che l'atomico non ti dà è una sorta di garanzia su quale di quei valori potresti ottenere. Atomic è comunemente comunemente confuso con l'essere thread-safe, e questo non è corretto. È necessario garantire la sicurezza del filo in altri modi. Tuttavia, atomic garantirà che se si tenta di leggere, si ottiene una sorta di valore.

nonatomic

Il rovescio della medaglia, non atomico, come si può probabilmente intuire, significa semplicemente "non fare quella roba atomica". Ciò che si perde è la garanzia di tornare sempre qualcosa. Se provi a leggere nel mezzo di una scrittura, puoi recuperare i dati inutili. Ma, d'altra parte, vai un po 'più veloce. Poiché le proprietà atomiche devono fare un po 'di magia per garantire che si ottenga un valore, sono un po' più lenti. Se si tratta di una proprietà a cui si sta accedendo molto, si consiglia di scendere a non anatomici per assicurarsi di non incorrere in tale penalità di velocità.

Vedi di più qui: https://realm.io/news/tmi-objective-c-property-attributes/


Atomico:

Atomic garantisce che l'accesso alla proprietà sarà eseguito in modo atomico. Ad esempio, restituisce sempre un oggetto completamente inizializzato, qualsiasi get / set di una proprietà su un thread deve essere completato prima che un altro possa accedervi.

Se si immagina che la seguente funzione che si verifica su due thread contemporaneamente, si possa capire perché i risultati non sarebbero belli.

-(void) setName:(NSString*)string
{
  if (name)
  {
    [name release]; 
    // what happens if the second thread jumps in now !?
    // name may be deleted, but our 'name' variable is still set!
    name = nil;
  }

  ...
}

Pro: il ritorno di oggetti completamente inizializzati ogni volta rende la scelta migliore in caso di multi-threading.

Contro: Colpo di prestazioni, rende l'esecuzione un po 'più lenta

Non Atomico:

A differenza di Atomic, non garantisce ogni volta il ritorno dell'oggetto completamente inizializzato.

Pro: esecuzione estremamente veloce.

Contro: Probabilità di valore spazzatura in caso di multi-threading.


Atomic è thread-safe , è lento e garantisce (non è garantito) che solo il valore bloccato è fornito indipendentemente dal numero di thread che tentano di accedere alla stessa zona. Quando si utilizza atomico, un pezzo di codice scritto all'interno di questa funzione diventa la parte della sezione critica, alla quale può essere eseguito un solo thread alla volta.

Assicura solo la sicurezza del filo; non lo garantisce. Ciò che intendo è che noleggi un autista esperto per la tua auto, tuttavia non garantisce che la macchina non incontri un incidente. Tuttavia, la probabilità rimane la minima.

Atomico: non può essere scomposto, quindi il risultato è previsto. Con nonatomico - quando un altro thread accede alla zona della memoria, può modificarlo, quindi il risultato è inaspettato.

Discorso a codice:

Atomic rende sicuro getter e setter del thread di proprietà. per esempio se hai scritto:

self.myProperty = value;

è thread-safe

[myArray addObject:@"Abc"] 

NON è thread sicuro.


Atomico significa che solo un thread accede alla variabile (tipo statico). Atomic è thread-safe, ma è lento.

Nonatomico significa che più thread accedono alla variabile (tipo dinamico). Nonatomico non è sicuro, ma è veloce.


Gli ultimi due sono identici; "atomico" è il comportamento predefinito (si noti che in realtà non è una parola chiave, ma è specificato solo dall'assenza di nonatomic - è stato aggiunto come parola chiave atomic nelle versioni recenti di llvm / clang).

Supponendo che tu stia @sintendendo l'implementazione del metodo, atomico e non atomico cambiano il codice generato. Se stai scrivendo il tuo setter / getter, atomico / non anatomico / conserva / assegna / copia sono solo di consulenza. (Nota: @synthesize è ora il comportamento predefinito nelle versioni recenti di LLVM. Non è inoltre necessario dichiarare variabili di istanza, anche esse saranno sintetizzate automaticamente e avranno un _ anteposto al loro nome per impedire l'accesso diretto accidentale).

Con "atomico", il setter / getter sintetizzato assicurerà che un valore intero sia sempre restituito dal getter o impostato dal setter, indipendentemente dall'attività del setter su qualsiasi altro thread. Cioè, se il thread A si trova nel mezzo del getter mentre il thread B chiama il setter, un valore reale valido - un oggetto autoreleased, molto probabilmente - verrà restituito al chiamante in A.

In nonatomic , non vengono fatte tali garanzie. Quindi, nonatomic è considerevolmente più veloce di "atomico".

Ciò che "atomico" non fa è una garanzia sulla sicurezza del filo. Se il thread A chiama il getter contemporaneamente con il thread B e C chiama il setter con valori diversi, il thread A può ottenere uno qualsiasi dei tre valori restituiti - quello prima di ogni setter chiamato o uno dei valori passati nei setter in B e C. Allo stesso modo, l'oggetto può finire con il valore di B o C, non c'è modo di dirlo.

Garantire l'integrità dei dati, una delle principali sfide della programmazione multi-thread, è ottenuto con altri mezzi.

In aggiunta a questo:

atomicity di una singola proprietà non può garantire la sicurezza del thread quando sono in gioco più proprietà dipendenti.

Tenere conto:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

In questo caso, il thread A potrebbe rinominare l'oggetto chiamando setFirstName: e quindi chiamando setLastName: Nel frattempo, il thread B può chiamare fullName tra le due chiamate del thread A e riceverà il nuovo nome associato al vecchio cognome.

Per risolvere questo problema, è necessario un modello transazionale . Cioè un altro tipo di sincronizzazione e / o esclusione che consente di escludere l'accesso a fullName mentre vengono aggiornate le proprietà dipendenti.


Ho trovato una spiegazione abbastanza bene delle proprietà atomiche e non atomiche here . Ecco un testo rilevante dello stesso:

'atomico' significa che non può essere rotto. Nei termini di programmazione / sistema operativo, una chiamata di funzione atomica è una che non può essere interrotta: l'intera funzione deve essere eseguita e non sostituita dalla CPU mediante il normale cambio di contesto del sistema operativo fino al suo completamento. Nel caso non lo sapessi: dato che la CPU può fare solo una cosa alla volta, il sistema operativo ruota l'accesso alla CPU a tutti i processi in esecuzione in intervalli di tempo ridotti, per dare l' illusione del multitasking. Lo scheduler della CPU può (e lo fa) interrompere un processo in qualsiasi momento della sua esecuzione - anche in una chiamata a metà chiamata. Quindi per azioni come l'aggiornamento di variabili contatore condivise in cui due processi potrebbero provare ad aggiornare la variabile allo stesso tempo, devono essere eseguite "atomicamente", cioè ogni azione di aggiornamento deve finire nella sua interezza prima che qualsiasi altro processo possa essere scambiato sul PROCESSORE.

Quindi immagino che atomico in questo caso significhi che i metodi del lettore di attributi non possono essere interrotti - in effetti significa che la variabile (s) che viene letta dal metodo non può cambiare il loro valore a metà perché alcuni altri thread / call / function ottengono scambiato sulla CPU.

Poiché le variabili atomic non possono essere interrotte, il valore in esse contenuto in qualsiasi punto è (thread-lock) garantito per essere non corrotto , anche se, assicurandosi che questo lock lock renda più lento l'accesso. non-atomic variabili non-atomic , d'altra parte, non offrono tale garanzia ma offrono il lusso di un accesso più rapido. Per riassumere, vai con non-atomic quando sai che le tue variabili non saranno accessibili simultaneamente da più thread e accelereranno le cose.


Il modo migliore per capire la differenza è usare il seguente esempio.

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 un setter o un getter, allora altri thread attenderanno.

Questo rende la proprietà "nome" in lettura / scrittura sicura, ma se un altro thread, D, chiama [name release] contemporaneamente, questa operazione potrebbe causare un arresto anomalo perché non è presente alcuna chiamata setter / getter. Ciò significa che un oggetto è in lettura / scrittura sicuro (ATOMIC), ma non thread-safe poiché un altro thread può inviare contemporaneamente qualsiasi tipo di messaggio all'oggetto. 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.


La sintassi e la semantica sono già ben definite da altre eccellenti risposte a questa domanda. Poiché l' esecuzione e le prestazioni non sono dettagliate bene, aggiungerò la mia risposta.

Qual è la differenza funzionale tra questi 3?

Avevo sempre considerato l'atomico come predefinito piuttosto curioso. A livello di astrazione a cui lavoriamo, utilizzando le proprietà atomiche per una classe come veicolo per ottenere il 100% di sicurezza del filo è un caso limite. Per i programmi multithread veramente corretti, l'intervento del programmatore è quasi certamente un requisito. Nel frattempo, le caratteristiche e l'esecuzione delle prestazioni non sono state ancora dettagliate in dettaglio. Avendo scritto alcuni programmi pesantemente multithread nel corso degli anni, avevo dichiarato le mie proprietà come non nonatomic tutto il tempo perché l'atomica non era sensibile per alcuno scopo. Durante la discussione dei dettagli delle proprietà atomiche e nonatomiche di questa domanda , ho fatto alcuni profiling incontrando alcuni risultati curiosi.

Esecuzione

Ok. La prima cosa che vorrei chiarire è che l'implementazione del blocco è definita dall'implementazione e astratta. Louis usa @synchronized(self) nel suo esempio: ho visto questo come una fonte comune di confusione. L'implementazione in realtà non usa @synchronized(self) ; usa le serrature a livello di oggetto. L'illustrazione di Louis è valida per un'illustrazione di alto livello che usa costrutti a noi tutti familiari, ma è importante sapere che non usa @synchronized(self) .

Un'altra differenza è che le proprietà atomiche manterranno / rilasceranno il ciclo degli oggetti all'interno del getter.

Prestazione

Ecco la parte interessante: le prestazioni che utilizzano gli accessi alle proprietà atomiche nei casi non contestati (ad es. Single-thread) possono essere molto veloci in alcuni casi. In casi meno che ideali, l'uso di accessi atomici può costare più di 20 volte il sovraccarico di nonatomic . Mentre il caso Contested utilizzando 7 thread è stato 44 volte più lento per la struttura a tre byte ( Core i7 da 2.2 GHz, x86_64). La struttura a tre byte è un esempio di una proprietà molto lenta.

Interessante nota a margine: gli accessori definiti dall'utente della struttura a tre byte erano 52 volte più veloci degli accessori atomici sintetizzati; o 84% della velocità degli accessori non atomici sintetizzati.

Gli oggetti nei casi contestati possono anche superare 50 volte.

A causa del numero di ottimizzazioni e variazioni nelle implementazioni, è abbastanza difficile misurare gli impatti del mondo reale in questi contesti. Potresti spesso sentire qualcosa come "Fidati di esso, a meno che non profili e trovi che è un problema". A causa del livello di astrazione, in realtà è abbastanza difficile misurare l'impatto reale. Ridurre i costi effettivi dai profili può richiedere molto tempo e, a causa delle astrazioni, è piuttosto impreciso. Inoltre, ARC vs MRC può fare una grande differenza.

Quindi, facciamo un passo indietro, senza concentrarci sull'implementazione degli accessi alle proprietà, includeremo i soliti sospetti come objc_msgSend ed esamineremo alcuni risultati ad alto livello del mondo reale per molte chiamate a un getter NSString in casi non contestati (valori in secondi):

  • MRC | nonatomico | getter implementati manualmente: 2
  • MRC | nonatomico | getter sintetizzato: 7
  • MRC | atomico | getter sintetizzato: 47
  • ARC | nonatomico | getter sintetizzato: 38 (nota: l'ARC aggiunge il conteggio dei riferimenti ciclicamente qui)
  • ARC | atomico | getter sintetizzato: 47

Come probabilmente avete intuito, l'attività di conteggio dei riferimenti / ciclismo è un contributo significativo con l'atomica e sotto ARC. Vedresti anche maggiori differenze nei casi contestati.

Anche se presta molta attenzione alle prestazioni, dico ancora Semantics First! . Nel frattempo, le prestazioni sono una bassa priorità per molti progetti. Tuttavia, conoscere i dettagli di esecuzione e i costi delle tecnologie che utilizzi certamente non guasta. Dovresti usare la tecnologia giusta per i tuoi bisogni, scopi e capacità. Speriamo che questo ti risparmi alcune ore di confronto e ti aiuti a prendere una decisione più informata quando progetti i tuoi programmi.


Prima la risposta più semplice: non c'è differenza tra i tuoi secondi due esempi. Per impostazione predefinita, i metodi di accesso alle proprietà sono atomici.

Gli accessor atomici in un ambiente non garbage collection (ossia quando si utilizza retain / release / autorelease) utilizzeranno un lock per assicurarsi che un altro thread non interferisca con l'impostazione / acquisizione corretta del valore.

Vedere la sezione " Prestazioni e discussioni " della documentazione di Apple Objective-C 2.0 per ulteriori informazioni e per altre considerazioni quando si creano app multi-thread.


Questo è spiegato nella documentation di Apple, ma di seguito sono riportati alcuni esempi di ciò che sta realmente accadendo. Si noti che non esiste una parola chiave "atomica", se non si specifica "nonatomico", la proprietà è atomica, ma specificando "atomico" esplicitamente si verificherà un errore.

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

Ora, la variante atomica è un po 'più complicata:

//@property(retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    UITextField *retval = nil;
    @synchronized(self) {
        retval = [[userName retain] autorelease];
    }
    return retval;
}

- (void) setUserName:(UITextField *)userName_ {
    @synchronized(self) {
      [userName_ retain];
      [userName release];
      userName = userName_;
    }
}

Fondamentalmente, la versione atomica deve prendere un lock per garantire la sicurezza del thread, e anche il conteggio dei ref sull'oggetto (e il conteggio automatico per bilanciarlo) in modo che l'oggetto sia garantito per il chiamante, altrimenti lì è una potenziale condizione di competizione se un altro thread sta impostando il valore, facendo cadere il conteggio dei ref a 0.

Esistono in realtà un gran numero di diverse varianti di come funzionano queste cose a seconda che le proprietà siano valori o oggetti scalari e come interagire tra conservazione, copia, sola lettura, non anatomica, ecc. In generale i sintetizzatori di proprietà sanno solo come fare la "cosa giusta" per tutte le combinazioni.



Proprietà atomiche : - Quando una variabile assegnata con proprietà atomiche significa che ha solo un accesso al thread e sarà thread-safe e sarà buona in prospettiva delle prestazioni, avrà un comportamento predefinito.

Proprietà non atomiche : - Quando una variabile assegnata con proprietà atomiche significa che ha accesso multi-thread e non sarà thread-safe e sarà lenta in prospettiva delle prestazioni, avrà un comportamento predefinito e quando due thread differenti vogliono accedere alla variabile contemporaneamente darà risultati inaspettati.


La proprietà atomica garantisce di mantenere un valore completamente inizializzato indipendentemente dal numero di thread che stanno eseguendo getter & setter su di esso.

La proprietà nonatomica specifica 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 semplificare l'intera confusione, comprendiamo il blocco mutex.Mutex lock come per il nome blocca la mutabilità dell'oggetto.Così se l'oggetto è accessibile da una classe nessun altra classe può accedere allo stesso oggetto.In iOS @sychronise fornisce anche il mutex lock.Ora serve in modalità FIFO e garantisce che il flusso non sia influenzato da due classi che condividono la stessa istanza. Tuttavia, se l'attività si trova sul thread principale, evitare l'accesso all'oggetto usando proprietà atomiche poiché potrebbe contenere l'interfaccia utente e degradare le prestazioni


La verità è che usano spin lock per implementare la proprietà atomica. Il codice come di seguito:

 static inline void reallySetProperty(id self, SEL _cmd, id newValue, 
      ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
    {
        id oldValue;
        id *slot = (id*) ((char*)self + offset);

        if (copy) {
            newValue = [newValue copyWithZone:NULL];
        } else if (mutableCopy) {
            newValue = [newValue mutableCopyWithZone:NULL];
        } else {
            if (*slot == newValue) return;
            newValue = objc_retain(newValue);
        }

        if (!atomic) {
            oldValue = *slot;
            *slot = newValue;
        } else {
            spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
            _spin_lock(slotlock);
            oldValue = *slot;
            *slot = newValue;        
            _spin_unlock(slotlock);
        }

        objc_release(oldValue);
    }

Prima di iniziare: è necessario sapere che ogni oggetto in memoria deve essere rilasciato dalla memoria affinché una nuova scrittura avvenga. Non puoi semplicemente scrivere sopra qualcosa come fai sulla carta. È necessario prima cancellare (dealloc) e poi si può scrivere su di esso. Se nel momento in cui la cancellazione è terminata (o a metà) e nulla è stato ancora scritto (o scritto a metà) e si prova a leggerlo, potrebbe essere molto problematico! Atomico e non anatomico ti aiutano a trattare questo problema in modi diversi.

Prima leggi this domanda e poi leggi la risposta di Bbum . Inoltre, leggi il mio riassunto.

atomic Garantirà SEMPRE

  • Se due persone diverse vogliono leggere e scrivere allo stesso tempo, il tuo documento non si limiterà a bruciare! -> La tua applicazione non si bloccherà mai, anche in condizioni di gara.
  • Se una persona sta cercando di scrivere e ha solo scritto 4 delle 8 lettere da scrivere, allora non può leggere nel mezzo, la lettura può essere fatta solo quando tutte e 8 le lettere sono scritte -> Non leggere (ottenere) avverrà su 'un thread che sta ancora scrivendo', cioè se ci sono 8 byte in byte da scrivere, e solo 4 byte sono scritti - fino a quel momento, non ti è permesso leggere da esso. Ma dal momento che ho detto che non si arresterà, leggerà dal valore di un oggetto autoreleased .
  • Se prima di scrivere si ha cancellato quella che in precedenza era scritto su carta e poi qualcuno vuole leggere si può ancora leggere. Come? Leggerai qualcosa di simile a Mac OS Cestino (poiché il cestino non è ancora cancellato al 100% ... è in un limbo) ---> Se ThreadA deve essere letto mentre ThreadB è già stato deallocato per scrivere, potresti o ottieni valore dal valore finale completamente scritto da ThreadB o ottieni qualcosa dal pool di autorelease.

Mantenere i conteggi è il modo in cui la memoria è gestita in Objective-C. Quando si crea un oggetto, ha un conteggio di ritenzione di 1. Quando si invia un oggetto a un messaggio di conservazione, il suo conteggio di mantenimento viene incrementato di 1. Quando si invia un oggetto un messaggio di rilascio, il suo conteggio di conservazione viene decrementato di 1. Quando si invia un oggetto a un messaggio di autorelease , il suo conteggio di mantenimento viene decrementato di 1 in qualche fase futura. Se il numero di ritenzione di un oggetto è ridotto a 0, viene deallocato.

  • Atomic non garantisce la sicurezza del filo, sebbene sia utile per ottenere la sicurezza del filo. Thread Safety è relativo al modo in cui scrivi il tuo codice / da quale coda di file stai leggendo / scrivendo. Garantisce solo il multithreading non intercambiabile.

Aspetta cosa?! Il multithreading e la sicurezza del thread sono diversi?

Sì.Multithreading significa: più thread possono leggere contemporaneamente una parte di dati condivisa e non si arresta in modo anomalo, tuttavia non garantisce che non si stia leggendo da un valore non autoreleased. Con la sicurezza del thread, è garantito che ciò che leggi non viene rilasciato automaticamente. La ragione per cui non rendiamo tutto atomico di default è, perché c'è un costo in termini di prestazioni e per la maggior parte delle cose non c'è davvero bisogno della sicurezza del thread. Alcune parti del nostro codice ne hanno bisogno e per quelle poche parti abbiamo bisogno di scrivere il nostro codice in modo thread-safe usando lock, mutex o sincronizzazione.

nonatomic

  • Dato che non esiste una cosa come Mac OS Trash Bin, a nessuno importa se ottieni o meno un valore (<- Questo potrebbe portare a un crash), né a nessuno importa se qualcuno prova a leggere a metà strada attraverso la scrittura (anche se la scrittura a metà strada è molto diversa dalla metà sulla scrittura su carta, a memoria potrebbe darti un valore stupido da prima, mentre sulla carta vedi solo metà di ciò che è stato scritto) -> Non garantisce di non bloccarsi, perché non usa il meccanismo di autorelease.
  • Non garantisce la lettura completa dei valori scritti!
  • È più veloce di atomico

Complessivamente sono diversi in 2 aspetti:

  • Crashing o meno a causa del fatto di avere o meno il pool di autorelease.

  • Permettendo di essere letto proprio nel mezzo di una "scrittura non ancora finita o valore vuoto" o non permettendo e consentendo solo di leggere quando il valore è completamente scritto.


Se stai usando la tua proprietà nel codice multi-thread, allora sarai in grado di vedere la differenza tra attributi non atomici e atomici. Nonatomico è più veloce di atomico e atomico è thread-safe, non nonatomico.

Vijayendra Tripathi ha già dato un esempio per un ambiente multi-thread.


  • -Atomico significa che solo un thread accede alla variabile (tipo statico).
  • -Atomic è thread-safe.
  • -ma è lento nelle prestazioni

Come dichiarare:

Siccome l'atomico è di default così,

@property (retain) NSString *name;

E nel file di implementazione

self.name = @"sourov";

Supponiamo che un'attività sia correlata a tre proprietà

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

Tutte le proprietà funzionano parallelamente (come in modo asincrono).

Se chiami "nome" dal thread A ,

E

Allo stesso tempo, se chiami

[self setName:@"Datta"]

dalla discussione B ,

Ora Se * nome proprietà non è anatomico allora

  • Restituirà il valore "Datta" per A
  • Restituirà il valore "Datta" per B

Ecco perché non atomico è chiamato thread non sicuro, ma è veloce nelle prestazioni a causa dell'esecuzione parallela

Ora Se * la proprietà nome è atomica

  • Garantirà valore "Sourov" per A
  • Quindi restituirà il valore "Datta" per B

Ecco perché atomic si chiama thread Safe ed è per questo che si chiama read-write safe

Tale operazione di situazione si realizzerà in serie. E lento nelle prestazioni

- Nonatomico significa accesso multiplo alla variabile (tipo dinamico).

- Nonatomic è thread non sicuro.

- ma è veloce nelle prestazioni

-Nonatomico NON è un comportamento predefinito, dobbiamo aggiungere una parola chiave non anatomica nell'attributo della proprietà.

For In Swift Conferma che le proprietà di Swift non sono anatomiche nel senso ObjC. Una ragione è quindi che pensi se l'atomicità per proprietà sia sufficiente per le tue esigenze.

Riferimento: https://forums.developer.apple.com/thread/25642

Per maggiori informazioni visita il sito http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html





nonatomic