web-dev-qa-db-fra.com

Explication du stockage fort et faible dans iOS5

Je suis nouveau dans le développement iOS5 et j'utilise Objective-C. J'ai du mal à comprendre la différence entre forte et faible mémoire. J'ai lu la documentation et d'autres SO questions, mais elles ont toutes le même son identique à moi, sans autre idée.

J'ai lu la documentation: Transitioning To ARC - il fait référence aux termes de conservation, d'attribution et de publication iOS4; qui me confond. Ensuite, je regarde Open U CS193p, qui distingue fort et faible:

Strong : "conservez-le dans le tas jusqu'à ce que je ne le pointe plus"
Faible : "conservez-le aussi longtemps que quelqu'un le pointe du doigt fortement"

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

113
KMC

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

Peut-être un exemple est en ordre.

Imaginez que notre objet soit un chien et que celui-ci veuille fuir (être désalloué).

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

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

Dès que le dernier pointeur fort (leash) ne pointe plus vers un objet, celui-ci est désalloué et tous les pointeurs faibles sont mis à zéro.

508
BJ Homer

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

Absolument pas. La principale différence entre les deux définitions que vous avez mentionnées est la "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 indicateurs pour <some_object>, un fort et un faible. Si nous définissons strongObject sur nil comme suit:

strongObject = nil;

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

  1. Strong: "garde ça dans le tas jusqu'à ce que je ne pointe plus dessus"

    strongObject ne pointe pas vers <some_object> plus. Donc, nous n'avons pas besoin de le garder.

  2. Faible: "conservez-le aussi longtemps que quelqu'un le pointe du doigt"

    weakObject pointe toujours sur <some_object>. Mais puisque personne else y pointe du doigt, cette règle signifie également que nous n’avons pas besoin de la garder.

Le résultat est que <some_object> est désalloué et si votre environnement d’exécution le prend en charge (Lion et iOS 5 et plus), alors weakObject sera automatiquement défini sur nil.

Considérons maintenant ce qui se passe si nous définissons weakObject sur nil comme suit:

weakObject = nil;

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

  1. Strong: "garde ça dans le tas jusqu'à ce que je ne pointe plus dessus"

    strongObject pointe sur <some_object>. Nous devons donc le garder.

  2. Faible: "conservez-le aussi longtemps que quelqu'un le pointe du doigt"

    weakObject ne pointe pas vers <some_object>.

Le résultat est que <some_object> est pas désalloué, mais weakObject sera le pointeur nil.

[Notez que tout cela suppose <some_object> n'est pas désigné par une autre référence forte ailleurs/par un autre moyen d'être "retenu"]

34
mattjgalloway

Fort

  1. Crée la propriété entre la propriété et la valeur assignée.
  2. Par défaut, il s'agit de la propriété d'objet dans ARC. Cela vous évite donc de vous soucier du nombre de références et de libérer la référence automatiquement.
  3. C'est un remplacement pour retenir. Nous utilisons si et seulement si nous devons utiliser comme retenue.

Faible

  1. Crée des non-propriétés entre la propriété et la valeur assignée.
  2. Strong est utilisé sur l'objet parent et faiblement sur l'objet enfant lorsque le parent est libéré, la référence de l'objet enfant est également définie sur nil.
  3. Il aide à prévenir 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 attribué, propriété non rétablie.
2
Shashi3456643

Autre exemple: L'étudiant est un Object, supposé pouvoir obtenir son diplôme (deallocate) tant qu'il a terminé tous les cours de base (strong pointers), qu’il suive ou non des cours optionnels (weak pointers). En d'autres termes: le pointeur fort est le seul facteur de désallocation de ce Object.

2
rObOtAndChalie

Non, ils ne sont pas identiques mais très différents. Vous utilisez fort uniquement si vous devez conserver l'objet. Vous utilisez faible sur n'importe quel autre cas, avec l'avantage que vous pouvez savoir si un objet a été retiré du tas car personne ne le conserve.

1
Gabriel

Je sais que je suis assez en retard pour ce parti, mais je pense qu'il est important de confondre le problème en soulignant que la signification de "modèles de mémoire forts et faibles" dépend de si vous parlez de logiciel ou de matériel.

Pour le matériel, faible ou fort indique si la cohérence séquentielle est prise en charge.

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

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

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 importance pour la programmation. Cette question même mentionne iOS, qui s'exécute généralement sur les processeurs Arm7. Arm7 a un modèle de mémoire faible. Pour les programmeurs habitués aux processeurs avec un modèle puissant - c'est-à-dire à nous tous car x86 et x64 ont un modèle puissant - 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 puissant. Le même code sur Arm ne fonctionne pas du tout, à moins que vous ne marquiez le drapeau comme volatil, et même dans ce cas, il est erratique.

S'il est vrai qu'Arm8 + change radicalement cette situation avec un support explicite pour l'acquisition/la publication, les logiciels hérités n'utilisent pas ce support. Les logiciels hérités incluent les trois systèmes d’exploitation téléphoniques et tout ce qui s’exécute, ainsi que les compilateurs et les bibliothèques jusqu’à leur mise à jour.

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

1
Peter Wone