9
votes

Comment fonctionne la gestion de la mémoire SWIFT?

Plus précisément, comment fonctionne Swift Memor Management avec des options d'option à l'aide du modèle de délégué?

Être habitué à écrire le schéma délégué dans l'objectif-C, mon instinct est de rendre le délégué faible . Par exemple, dans l'objectif-c: xxx

Cependant, ce faisant, ce faisant, n'est pas si simple.

Si nous avons juste une normale Protocole de recherche: xxx

Nous ne pouvons pas déclarer des variables de ce type comme faible: xxx

produit l'erreur suivante:

'faible' ne peut pas être appliqué au type non de classe 'Foodelegate'

Nous n'utilisons pas le mot-clé faible , ce qui nous permet d'utiliser structs et énums en tant que délégués, Ou nous modifions notre protocole sur les éléments suivants: xxx

qui nous permet d'utiliser faible , mais ne nous permet pas d'utiliser structs < / code> ou énums .

Si je ne fais pas mon protocole de protocole de classe, et n'utilise donc pas faible pour ma variable, i 'm Création d'un cycle de conserver, correct?

Y a-t-il une raison imaginable pour laquelle tout protocole destiné à être utilisé comme protocole de délégué ne devrait pas être un protocole de classe afin que les variables de ce type puissent être faible ?

Je demande principalement, car dans la section de délégation de La documentation officielle Apple sur les protocoles SWIFT , ils fournissent un exemple de protocole non de classe et une variable non faible utilisée comme délégué à leur classe: xxx xxx

devrons-nous prendre cela comme un indice que Apple pense que nous devrions utiliser Structs en tant que délégués? Ou est-ce simplement un mauvais exemple, et de manière réaliste, des protocoles délégués devraient être déclarés sous forme de protocoles de classe que pour que l'objet délégué puisse tenir une faible référence à son délégué?


4 commentaires

"Si je ne fais pas mon protocole de protocole, un protocole de classe et que je n'utilise donc pas faible pour ma variable, je crée un cycle de conservation, correct?" Non, pas correct. Pas à moins que le délégué conserve une référence à son hôte. Dans l'exemple Swift, cela n'arrive pas. Le DiceGameDelegate a des paramètres Dicegame dans ses fonctions, mais il n'a pas de bibliothèque propriété qui causerait une référence persistante à son hôte.


Mais dans la plupart des cas d'utilisation réels, le délégué a une référence à l'objet délégué.


Correct, et c'est exactement ce que ma réponse parle de. - Vous avez demandé, fondamentalement, ce qui est spécial à propos de cet exemple Apple qui fait pas utilise une classe et un délégué faible, et je vous l'ai dit.


duplicache possible de Comment puis-je faire une référence de protocole faible dans 'pure' Swift (W / O @OBJC)


3 Réponses :


7
votes

Devrions-nous prendre cela comme indice que Apple pense que nous devrions utiliser des structures comme des délégués? Ou est-ce simplement un mauvais exemple, et de manière réaliste, les protocoles délégués devraient être déclarés des protocoles de classe que pour que l'objet délégué puisse tenir une faible référence à son délégué?

Voici la chose. Dans la programmation de cacao de la vie réelle, le délégué est probablement une classe existante. C'est une classe car il existe à peu près à un autre but que seule une classe peut satisfaire - car Cocoa l'exige .

Par exemple, très souvent, pour prendre iOS à titre d'exemple, un contrôleur d'évaluation doit servir de délégué du contrôleur d'affichage aux fins d'organiser un message entre eux. La propriété des contrôleurs d'affichage est dictée par la hiérarchie du contrôleur de vue et de rien d'autre. Donc, à Swift, comme dans l'objectif-c, vous aviez meilleur faire ce délégué propriété faible , car il serait terrible si une vue Le contrôleur a soudainement pris la propriété de la gestion de la mémoire d'un autre contrôleur d'affichage!

Donc, dans le monde réel du cadre de cacao, il y a un grave danger de propriété incorrecte ou d'un cycle de retenue. Et c'est le problème que faible résolvère. Mais cela ne fonctionne que lorsque vous le disez à juste titre, avec des cours.

L'exemple dans le livre, cependant, concerne certains objets vivant dans un monde swift isolé composé d'abstrait. Dans ce monde, tant que vous n'êtes pas en danger de circularité (conserver le cycle), il n'y a aucune raison de ne pas utiliser les structures et il n'y a aucune raison de s'inquiéter de la gestion de la mémoire. Mais ce monde n'est pas le monde que vous allez généralement programmer! Et ce monde n'est pas le cadre de cacao-cadre que votre modèle de délégué de l'objectif-C vient et appartient.


6 commentaires

Cette question n'est pas étiquetée avec iOS, et bien que j'ai déjà fait une programmation très peu OS X, je suis à peu près sûr que j'ai vu un nsarray sous-classe utilisée comme NSTABLABAASOURCE . Cela ne fait-il pas au moins un sens que je souhaiterais peut-être utiliser un tableau (qui est une structure à Swift) en tant que délégué de type DataSource?


Swift Array est une structure mais elle est pontée à Nsarray (la classe). -Cever, en réponse à votre question, non: Dans quel scénario possible serait une source de données? Les sources de données sont des choses capables de répondre aux questions de protocole de source de données. Vous n'aurez jamais de tableau faire cela.


@NHGRIF: Utilisation nsarray comme une source de données de table (dans OS X ou iOS) est une très mauvaise idée. Cela signifierait l'extension de la classe nsarray pour implémenter le ( ns | ui ) tableViewDataSource méthodes, ce qui signifierait Chaque tableau dans votre application peut agir comme une source de données possible pour votre vue table. Vous avez probablement vu CLASSES QUELQU'EMPLAGE VIEW MÉTHODES DE SOURCE DE DONNÉES Utilisation de Un tableau. L'argument de Matt tient au moins pour le cacao: les endroits où Cocoa (Touch) veut qu'un délégué soit des endroits qui exigent un type de classe et continueront probablement à être.


@Rickster C'était un Nsarray Sous-classe . Tout comme nous allions normalement Sous-classe uiviewcontroller ... pas l'étendre ...


@nhgrif vous n'êtes pas censé sous-classe Nsarray parce que c'est un cluster de classe. Wrapper est un meilleur modèle ici, pour de nombreuses raisons.


Désolé, je suppose que j'ai passé trop de temps autour des gens qui veulent tout prolonger ces derniers temps. :) Ce n'est toujours pas le modèle habituel pour une source de données, même cela fonctionne dans certains cas - Cocao encourage la personnalisation par la composition, non pas sous-classement.



2
votes

Oui, cet exemple est un peu une bizarrerie.

Parce que l'exemple utilise un type de protocole non de classe, il faut s'attendre à une structure possible implémentant le protocole, ce qui signifie que l'instance Dicegame possède son délégué. Et en effet, qui enfreint les hypothèses typiques sur le schéma délégué.

Cela ne conduit pas à un cycle de référence dans ce cas car le dictiongameTracker est un objet fictif qui ne possède pas le DICEGAME elle-même - mais dans une application réelle, il est possible, voire probable qu'un délégué pourrait également être le propriétaire de l'objet déléguant. (Par exemple, un contrôleur d'affichage peut posséder le Dicegame et implémenter DICGameDelegate afin qu'il puisse mettre à jour son interface utilisateur en réponse aux événements de jeu.)

Ce type de cycle de référence se transformerait probablement en un désordre déroutant si le jeu, son délégué ou le type mettant en œuvre un ou les deux de ces protocoles ont été un type de valeur - car les types de valeur sont copiés, certaines des variables de votre La configuration finirait par être des copies distinctes du jeu (ou propriétaire du jeu).

Réalistiquement on s'attendrait à utiliser des types de référence (classes) pour la mettre en œuvre de toute façon, même si la déclaration de protocole quitte la possibilité de le faire autrement. Même dans un monde hypothétique Swift seulement, il est probablement logique de le faire de cette façon ... Généralement chaque fois que vous avez quelque chose avec une longue vie, un état mutable interne et un modèle d'utilisation qui l'accède à d'autres acteurs potentiellement multiples, vous Vous voulez un type de classe, même si vous pouvez trier de faux sinon avec des types de valeur et var .


0 commentaires

2
votes

Si vous devez avoir structs code> et émums code> dans votre protocole, si vous faites votre délégué nil code> juste avant de fermer le contrôleur de vue, Ensuite, cela enfreint le cycle de conservation. J'ai vérifié cela dans les allocations dans les instruments.

// view controller about to close
objectCreatedByMe.delegate = nil


3 commentaires

Il devrait être évident que cela enfreint le cycle. Mais il y a beaucoup de raisons pour lesquelles cela n'est pas assez bon ...


J'essayais juste de trouver une solution au problème. Que j'ai confirmé ceci est. Je ne sais pas pourquoi j'étais abattu pour ça. Pouvez-vous développer s'il vous plaît.


Je t'ai voté. Vous essayiez de répondre, vous n'avez rien mis mal à dire que je peux dire. Et si c'était faux, dans une semaine ou deux Apple changera la langue et vous auriez probablement raison. Swift se déplace à un rythme rapide. Je ne me lève pas trop dans les bras jusqu'à ce qu'il soit sur des plateaux. Heck ils viennent d'ajouter ensemble la semaine dernière.