Explication du stockage fort et faible dans iOS5

114

Je suis nouveau dans le développement iOS5 et j'utilise objective-c. J'ai du mal à comprendre la différence entre un stockage fort et faible . J'ai lu la documentation et d'autres questions SO, mais elles me paraissent toutes identiques sans plus d'informations.

J'ai lu la documentation: Transitioning To ARC - il fait référence aux termes iOS4 de conservation, d'attribution et de libération; ce qui me trouble. Ensuite, je regarde Open U CS193p, où il différencie le fort et le faible:

Strong : "garde ceci dans le tas jusqu'à ce que je ne le pointe plus"
Faible : "garde ceci tant que quelqu'un d'autre le pointe fortement"

Les deux définitions ne sont-elles pas identiques = si le pointeur ne pointe plus vers un objet, alors libérez la mémoire contenant l'objet? Je comprends le concept de pointeurs, de tas, d'allocation ou de désallocation de la mémoire - mais quelle est la différence entre fort et faible?

KMC
la source
Le modèle de gestion de la mémoire est toujours pertinent même si vous utilisez ARC. Vous devez toujours comprendre le comptage de références, vous n'avez tout simplement pas à le faire manuellement. Votre dernier paragraphe est donc une demande déraisonnable.
jrturton

Réponses:

509

La différence est qu'un objet sera désalloué dès qu'il n'y aura pas de pointeurs forts vers lui. Même si les pointeurs faibles pointent vers lui, une fois que le dernier pointeur fort est parti, l'objet sera désalloué et tous les pointeurs faibles restants seront remis à zéro.

Peut-être qu'un exemple est en ordre.

Imaginez que notre objet est un chien, et que le chien veut s'enfuir (être désalloué).

Les pointeurs forts sont comme une laisse sur le chien. Tant que vous avez la laisse attachée au chien, le chien ne s'enfuira pas. Si cinq personnes attachent leur laisse à un chien (cinq pointeurs puissants vers un objet), le chien ne s'enfuira pas tant que les cinq laisses ne seront pas détachées.

Les pointeurs faibles, par contre, sont comme de petits enfants qui pointent le chien et disent "Regarde! Un chien!" Tant que le chien est toujours en laisse, les petits enfants peuvent toujours voir le chien et ils le montreront toujours. Cependant, dès que toutes les laisses sont détachées, le chien s'enfuit, peu importe le nombre de petits enfants qui le désignent.

Dès que le dernier pointeur fort (laisse) ne pointe plus vers un objet, l'objet sera désalloué et tous les pointeurs faibles seront mis à zéro.

BJ Homer
la source
2
Il est basé sur une analogie que Malcom Crawford chez Apple a donnée il y a quelques années. Je ne sais pas où il l'a eu.
BJ Homer
Je me souviens avoir lu quelque chose de similaire (pré-arc) dans un livre, je pense que c'était Hillegass, mais ensuite il aurait pu l'obtenir ailleurs ... c'est un bon cependant!
jrturton
14
+1 excellent exemple. c'est un dérivé de l'exemple de Hillegass sur la façon dont les laisses sont retenues / libérées, mais j'adore cette adaptation pour fort / faible.
Dave DeLong
2
@DaveDeLong: Eh bien, ils sont illégaux sur 10.6 avec ARC. Vous ne pouvez pas du tout les utiliser. C'est donc un point hors de propos.
BJ Homer
5
Un autre bon est les ballons à l'hélium: tant qu'au moins une ficelle est tenue, elle ne va pas flotter. Les analogies laisse / ballon sont également bonnes pour amener les gens à oublier que la «propriété» est gérée par la rétention / libération.
Steve Weller
34

Les deux définitions ne sont-elles pas identiques.

Absolument pas. La principale différence entre les deux définitions que vous avez signalées est le «tant que quelqu'un d'autre». C'est le «quelqu'un d'autre» qui est important.

Considérer ce qui suit:

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

Maintenant, nous avons deux pointeurs vers <some_object>, un fort et un faible. Si nous nous mettons strongObjectà nilaimer ainsi:

strongObject = nil;

Ensuite, si vous suivez les règles que vous avez décrites, vous vous poserez les questions suivantes:

  1. Strong: "gardez ceci dans le tas jusqu'à ce que je ne le pointe plus"

    strongObjectne pointe <some_object>plus. Nous n'avons donc pas besoin de le garder.

  2. Faible: "gardez ceci aussi longtemps que quelqu'un d'autre l'indique fortement"

    weakObjectpointe toujours vers <some_object>. Mais puisque personne d' autre ne l' indique, cette règle signifie également que nous n'avons pas besoin de la garder.

Le résultat est qu'il <some_object>est désalloué et si votre environnement d'exécution le prend en charge (Lion et iOS 5 à partir de), il weakObjectsera automatiquement défini sur nil.

Maintenant, considérez ce qui se passe si nous nous mettons weakObjectà nilaimer ainsi:

weakObject = nil;

Ensuite, si vous suivez les règles que vous avez décrites, vous vous poserez les questions suivantes:

  1. Strong: "gardez ceci dans le tas jusqu'à ce que je ne le pointe plus"

    strongObjectpointe vers <some_object>. Nous devons donc le garder.

  2. Faible: "gardez ceci aussi longtemps que quelqu'un d'autre l'indique fortement"

    weakObjectne pointe pas <some_object>.

Le résultat est que ce <some_object>n'est pas désalloué, mais ce weakObjectsera le nilpointeur.

[Notez que tout ce qui est supposé <some_object>n'est pas indiqué par une autre référence forte ailleurs / par d'autres moyens d'être "détenu"]

mattjgalloway
la source
1
Ainsi, la principale différence entre fort et faible est que la désallocation des objets pointés fortement annulera automatiquement tous les pointeurs faibles associés. Et pour qu'un pointeur faible pointe vers quelque chose, il existe toujours un pointeur fort. Dans l'affirmative, l'objet principal de l'application doit-il être fortement pointé?
KMC
Pour qu'un pointeur faible pointe vers quelque chose de valide, alors oui, il doit y avoir un pointeur fort. Ajoutez à cela le fait qu'iOS 5 et Lion prennent en charge la suppression automatique des références faibles et vous obtenez ce que vous dites. Le runtime d'iOS 4 fait pas en charge cela cependant. Le "principal objet de l'application" Je suppose que vous voulez dire l' UIApplicationobjet? Cela sera fortement référencé par le fonctionnement interne de UIKit- mais vous n'avez pas à vous en soucier.
mattjgalloway
Je pense que vous pouvez utiliser le mot comme "strongObjectPointer" au lieu de "strongObject". Ainsi, les nouveaux venus à la programmation auront une meilleure signification. Belle prise sur @BJ Homer post Mr.Matt.Interesting :)
Vijay-Apple-Dev.blogspot.com
2

Fort

  1. Crée la propriété entre la propriété et la valeur attribuée.
  2. Il s'agit de la valeur par défaut de la propriété d'objet dans ARC afin de ne pas vous soucier du nombre de références et de libérer la référence automatiquement.
  3. Il remplace la rétention. Nous utilisons si et seulement si nous devons utiliser comme retenu.

Faible

  1. Crée des non-propriétés entre la propriété et la valeur attribuée.
  2. Strong est utilisé sur l'objet parent et faible est utilisé sur l'objet enfant lorsque le parent est libéré, la référence d'objet enfant est également définie sur nil
  3. Cela aide à empêcher les cycles de rétention.
  4. Il ne protège pas l'objet référencé lors de la collecte par garbage collector.
  5. Faible est essentiellement une propriété non conservée.
Shashi3456643
la source
Il convient de mentionner ici ce qu'est généralement le cycle de rétention. Nous avons deux objets: l'objet A et l'objet B. L'objet A a une forte référence à l'objet B et l'objet B a une forte référence à l'objet A. Rien d'autre n'a une forte référence à l'objet A ou B.
boro
2

Un autre exemple: l'étudiant est un Object, supposé qu'il / il peut obtenir son diplôme ( deallocate) tant qu'il / elle a terminé tous les cours de base ( strong pointers), peu importe s'il / elle prend des cours optionnels ( weak pointers). En d'autres termes: un pointeur fort est le seul facteur de désallocation de cela Object.

RobotCharlie
la source
1

Non, ils ne sont pas identiques mais très différents. Vous n'utilisez Strong que si vous devez conserver l'objet. Vous utilisez faible dans tous les autres cas, avec l'avantage de savoir si l'objet a été supprimé du tas parce que personne ne le conserve.

Gabriel
la source
1

Je sais que je suis plutôt en retard à cette soirée, mais je pense qu'il est important de confondre la question en soulignant que la signification de «modèles de mémoire forte et faible» dépend si vous parlez de logiciel ou de matériel.

Pour le matériel, faible ou fort indique s'il existe une prise en charge de la cohérence séquentielle.

[SC signifie que] ... le résultat de toute exécution est le même que si les opérations de tous les processeurs étaient exécutées dans un ordre séquentiel, et les opérations de chaque processeur individuel apparaissent dans cette séquence dans l'ordre spécifié par son programme. - Lamport, 1979

WTF est-ce que cela a à voir avec la mémoire? Cela implique que les écritures sur des variables par différents processeurs doivent être vues dans le même ordre par tous les processeurs. Dans le matériel avec un modèle solide, cela est garanti. Sur du matériel avec un modèle faible, ce n'est pas le cas.

Les réponses existantes n'interprètent la question qu'en termes de modèles de mémoire logicielle. Le matériel n'est pas sans rapport avec la programmation. Cette question même mentionne iOS, qui fonctionne généralement sur des processeurs Arm7. Arm7 a un modèle de mémoire faible. Pour les programmeurs habitués aux processeurs avec un modèle fort - ce qui est nous tous parce que x86 et x64 ont un modèle fort - c'est un piège terrible. L'utilisation d'un booléen pour signaler à un autre thread de quitter fonctionne bien dans un modèle fort. Le même code sur Arm ne fonctionne pas du tout à moins que vous ne marquiez le drapeau comme volatile, et même dans ce cas, il est erratique.

S'il est vrai qu'Arm8 + change complètement cela avec un support explicite pour l'acquisition / la publication, les logiciels hérités n'utilisent pas ce support. Le logiciel hérité comprend les trois systèmes d'exploitation de téléphone et tout ce qui fonctionne sur eux, ainsi que des compilateurs et des bibliothèques jusqu'à ce qu'ils soient mis à jour.

Pour un examen approfondi de ce sujet, je vous renvoie à l'inimitable Herb Sutter .

Peter Wone
la source