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.