Pourquoi les delegates Objective-C reçoivent-ils habituellement la propriété assignée au lieu de la conserver?

Je surfe sur le merveilleux blog maintenu par Scott Stevenson, et j'essaie de comprendre un concept fondamental d'Objective-C qui consiste à assigner aux delegates la propriété 'assign' par rapport à 'retain'. Notez que les deux sont les mêmes dans un environnement collecté. Je suis principalement concerné par un environnement non basé sur GC (par exemple: iPhone).

Directement sur le blog de Scott:

"Le mot key assign génère un setter qui affecte directement la valeur à la variable d'instance, plutôt que de la copyr ou de la conserver.C'est mieux pour les types primitifs comme NSInteger et CGFloat, ou les objects que vous ne possédez pas directement, comme les delegates."

Qu'est-ce que cela signifie que vous ne possédez pas directement l'object délégué? Je retiens généralement mes delegates, parce que si je ne veux pas qu'ils s'en aillent dans l'abîme, retenez-le pour moi. Je résume habituellement UITableViewController loin de son dataSource respectif et délègue également. Je retiens également cet object particulier. Je veux m'assurer qu'il ne disparaîtra jamais, donc mon UITableView a toujours son délégué autour.

Quelqu'un peut-il expliquer plus en détail où / pourquoi je me trompe, afin que je puisse comprendre ce paradigme commun dans la programmation Objective-C 2.0 de l'utilisation de la propriété assign sur les delegates au lieu de conserver?

Merci!

    La raison pour laquelle vous évitez de conserver des delegates est que vous devez éviter un cycle de conservation:

    A crée B A se positionne comme délégué de B … A est libéré par son propriétaire

    Si B avait retenu A, A ne serait pas libéré, puisque B possède A, donc le dealloc de A ne serait jamais appelé, provoquant une fuite de A et B.

    Vous ne devriez pas vous inquiéter du fait que A s'en va parce qu'il possède B et s'en débarrasse ainsi en dealloc.

    Parce que l'object envoyant les messages de délégué ne possède pas le délégué.

    Plusieurs fois, c'est l'inverse, comme lorsqu'un controller se définit comme délégué d'une vue ou d'une window: le controller possède la vue / window, donc si la vue / window possède son délégué, les deux objects se posséderaient mutuellement. Ceci, bien sûr, est un cycle de retenue, semblable à une fuite ayant la même conséquence (les objects qui devraient être morts restnt vivants).

    D'autres fois, les objects sont des pairs: aucun des deux ne possède l'autre, probablement parce qu'ils appartiennent tous les deux au même troisième object.

    De toute façon, l'object avec le délégué ne doit pas conserver son délégué.

    (Il y a au less une exception, en passant, je ne me souviens pas de ce que c'était, et je ne pense pas qu'il y avait une bonne raison à cela.)


    Addendum (ajouté le 2012-05-19): Sous ARC, vous devriez utiliser weak au lieu d' assign . Les references faibles sont définies sur nil automatiquement lorsque l'object meurt, ce qui élimine la possibilité que l'object délégué finisse par envoyer des messages au délégué décédé.

    Si vous restz à l'écart de l'ARC pour une raison quelconque, modifiez au less les propriétés d' unsafe_unretained qui pointent vers des objects sur unsafe_unretained , ce qui rend explicite qu'il s'agit d'une reference non retenue mais non nulle à un object.

    assign rest approprié pour les valeurs non-object sous ARC et MRC.

    Notez que lorsque vous avez un délégué assign, il est très important de toujours définir cette valeur de délégué à zéro chaque fois que l'object va être désalloué – donc un object doit toujours veiller à ignorer les references de délégué dans dealloc s'il n'a pas fait ailleurs.

    Une des raisons derrière cela est d'éviter les cycles de retenue. Juste pour éviter le scénario où A et B objectent les uns les autres et aucun d'entre eux n'est libéré de la memory.

    L' atsortingbution automatique est la meilleure pour les types primitifs tels que NSInteger et CGFloat, ou les objects que vous ne possédez pas directement, tels que les delegates.