Spiegazione di archiviazione forte e debole in iOS5


114

Sono nuovo nello sviluppo di iOS5 e utilizzo l'obiettivo-c. Ho difficoltà a capire la differenza tra forte archiviazione e debole . Ho letto la documentazione e altre domande SO, ma suonano tutte identiche a me senza ulteriori approfondimenti.

Ho letto la documentazione: Transitioning To ARC - fa riferimento ai termini di conservazione, assegnazione e rilascio di iOS4; che mi confonde. Quindi guardo in Open U CS193p, dove differenzia forte e debole:

Forte : "tienilo nel mucchio finché non lo indico più"
Debole : "tienilo finché qualcun altro lo indica con forza"

Le due definizioni non sono identiche = se il puntatore non punta più a un oggetto, quindi libera la memoria che contiene l'oggetto? Comprendo il concetto di puntatori, mucchio, allocazione o deallocazione della memoria, ma qual è la differenza tra forte e debole?


Il modello di gestione della memoria è ancora rilevante anche se stai utilizzando ARC. Devi ancora capire il conteggio dei riferimenti, semplicemente non devi farlo manualmente. Quindi il tuo ultimo paragrafo è una richiesta irragionevole.
jrturton

Risposte:


509

La differenza è che un oggetto verrà deallocato non appena non ci saranno forti puntatori ad esso. Anche se i puntatori deboli puntano ad esso, una volta che l'ultimo puntatore forte è andato, l'oggetto verrà deallocato e tutti i puntatori deboli rimanenti verranno azzerati.

Forse è necessario un esempio.

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.


2
Si basa su un'analogia che Malcom Crawford della Apple ha fornito alcuni anni fa. Non so dove l'abbia preso.
BJ Homer

Ricordo di aver letto qualcosa di simile (pre-arco) in un libro, penso che fosse Hillegass, ma poi avrebbe potuto ottenerlo da qualche altra parte ... è comunque buono!
jrturton

14
+1 ottimo esempio. è un derivato dell'esempio di Hillegass su come i guinzagli vengono trattenuti / rilasciati, ma adoro questo adattamento per forte / debole.
Dave DeLong

2
@ DaveDeLong: Beh, sono illegali sulla 10.6 con ARC. Non puoi usarli affatto. Quindi questo è un punto irrilevante.
BJ Homer

5
Un altro buono sono i palloncini di elio: finché si tiene almeno una corda, non galleggerà via. Le analogie tra guinzaglio / palloncino sono utili anche per far dimenticare alle persone che la "proprietà" è gestita dal ritegno / rilascio.
Steve Weller

34

Le due definizioni non sono identiche.

Assolutamente no. La differenza fondamentale tra le due definizioni che hai evidenziato è "finché qualcun altro". È il "qualcun altro" che è importante.

Considera quanto segue:

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

Ora abbiamo due indicazioni <some_object>, una forte e una debole. Se abbiamo impostato strongObjecta nilquesto modo:

strongObject = nil;

Quindi, se segui le regole che hai delineato, ti farai queste domande:

  1. Forte: "tienilo nel mucchio finché non lo indico più"

    strongObjectnon indica <some_object>più. Quindi non abbiamo bisogno di tenerlo.

  2. Debole: "mantienilo finché qualcun altro lo indica con forza"

    weakObjectindica ancora <some_object>. Ma poiché nessun altro lo indica, questa regola significa anche che non è necessario mantenerlo.

Il risultato è che <some_object>viene deallocato e se il tuo runtime lo supporta (Lion e iOS 5 in poi) weakObjectverrà automaticamente impostato su nil.

Ora considera cosa succede se impostiamo weakObjectin questo nilmodo:

weakObject = nil;

Quindi, se segui le regole che hai delineato, ti farai queste domande:

  1. Forte: "tienilo nel mucchio finché non lo indico più"

    strongObjectpunta a <some_object>. Quindi dobbiamo tenerlo.

  2. Debole: "mantienilo finché qualcun altro lo indica con forza"

    weakObjectnon punta a <some_object>.

Il risultato è che non<some_object> viene deallocato, ma sarà il puntatore.weakObjectnil

[Nota che tutto ciò che sta assumendo <some_object>non è indicato da un altro forte riferimento da qualche altra parte / qualche altro mezzo per essere "trattenuto"]


1
Quindi la differenza principale tra forte e debole è che la deallocazione di oggetti puntati con forza annullerà automaticamente tutti i relativi indicatori deboli. E affinché un puntatore debole punti a qualcosa, esiste sempre un puntatore forte. In caso affermativo, l'oggetto principale dell'applicazione deve essere fortemente puntato?
KMC

Affinché un puntatore debole punti a qualcosa di valido, sì, deve esserci un puntatore forte. Aggiungete a ciò il fatto che iOS 5 e Lion supportano l'auto-nilling dei riferimenti deboli e otterrete quello che dite. Il runtime di iOS 4 non lo supporta però. L '"oggetto principale dell'applicazione" presumo tu intenda l' UIApplicationoggetto? Ciò sarà fortemente referenziato dal funzionamento interno di UIKit- ma non devi preoccuparti di questo.
mattjgalloway

Penso che tu possa usare la parola come "strongObjectPointer" invece di "strongObject". Quindi le nuove persone alla programmazione avranno un significato migliore. Bella presa su @BJ Homer post Mr.Matt.Interesting :)
Vijay-Apple-Dev.blogspot.com

2

Forte

  1. Crea proprietà tra proprietà e valore assegnato.
  2. Questa è l'impostazione predefinita per la proprietà dell'oggetto in ARC, quindi non ti consente di preoccuparti del conteggio dei riferimenti e rilascia il riferimento automaticamente.
  3. È la sostituzione per il mantenimento. Usiamo se e solo se abbiamo bisogno di usare come ritegno.

Debole

  1. Crea non proprietà tra proprietà e valore assegnato.
  2. Strong viene utilizzato sull'oggetto genitore e weak viene utilizzato sull'oggetto figlio quando il genitore viene rilasciato, quindi anche il riferimento all'oggetto figlio è impostato su nil
  3. Aiuta a prevenire i cicli di conservazione.
  4. Non protegge l'oggetto a cui si fa riferimento durante la raccolta tramite Garbage Collector.
  5. Debole è essenzialmente assegnata, proprietà non mantenuta.

Vale la pena menzionare qui cosa è tipicamente il ciclo di conservazione. Abbiamo due oggetti: l'oggetto A e l'oggetto B. L'oggetto A ha un forte riferimento all'oggetto B e l'oggetto B ha un forte riferimento all'oggetto A. Nient'altro ha un forte riferimento all'oggetto A o B.
boro

2

Un altro esempio: lo studente è un Object, suppone che possa diplomarsi ( deallocate) fintanto che ha finito tutti i corsi di base ( strong pointers), indipendentemente dal fatto che prenda corsi opzionali ( weak pointers). In altre parole: un puntatore forte è l'unico fattore di deallocazione di ciò Object.


1

No, non sono identici ma molto diversi. Usi forte solo se hai bisogno di trattenere l'oggetto. Usi debole in qualsiasi altro caso, con il vantaggio che puoi sapere se l'oggetto è stato rimosso dall'heap perché nessuno lo conserva.


1

So di essere piuttosto in ritardo a questa festa, ma penso sia importante confondere la questione sottolineando che il significato di "modelli di memoria forti e deboli" dipende dal fatto che si parli di software o hardware.

Per l'hardware, debole o forte indica se è disponibile il supporto per la coerenza sequenziale.

[SC significa che] ... il risultato di qualsiasi esecuzione è lo stesso come se le operazioni di tutti i processori fossero eseguite in un certo ordine sequenziale, e le operazioni di ogni singolo processore appaiono in questa sequenza nell'ordine specificato dal suo programma. - Lamport, 1979

Cosa ha a che fare con la memoria? Implica che le scritture su variabili da processori differenti debbano essere viste nello stesso ordine da tutti i processori. In hardware con un modello robusto questo è garantito. Su hardware con un modello debole, non lo è.

Le risposte esistenti interpretano la domanda solo in termini di modelli di memoria software. L'hardware non è irrilevante per la programmazione. Questa stessa domanda menziona iOS, che in genere gira su processori Arm7. Arm7 ha un modello di memoria debole. Per i programmatori abituati a processori con un modello forte - che è per tutti noi perché x86 e x64 hanno un modello forte - questa è una trappola terribile. Usare un bool per segnalare a un altro thread di uscire funziona bene in un modello forte. Lo stesso codice su Arm non funziona affatto a meno che non si contrassegni il flag come volatile, e anche in questo caso è irregolare.

Mentre è vero che Arm8 + cambia completamente questo con il supporto esplicito per acquisizione / rilascio, il software legacy non utilizza questo supporto. Il software legacy include tutti e tre i sistemi operativi del telefono e tutto ciò che viene eseguito su di essi, nonché compilatori e librerie fino a quando non vengono aggiornati.

Per un approfondito approfondimento di questo argomento vi rimando all'inimitabile Herb Sutter .

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.