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?
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.
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:
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.
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:
Strong: "garde ça dans le tas jusqu'à ce que je ne pointe plus dessus"
strongObject
pointe sur <some_object>
. Nous devons donc le garder.
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"]
Fort
Faible
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
.
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.
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 .