Comment puis-je faire d'une faiblesse du protocole de référence dans la "pure" Swift (sans @objc)
weak
références ne semble pas fonctionner dans Swift, à moins qu'un protocol
est déclarée comme @objc
, que je ne veux pas d'un pur Swift app.
Ce code donne une erreur de compilation (weak
ne peut pas être appliquée à des non-type de classe MyClassDelegate
):
class MyClass {
weak var delegate: MyClassDelegate?
}
protocol MyClassDelegate {
}
J'ai besoin de préfixe de protocole avec @objc
, puis il travaille.
Question: qu'est-Ce que la "pure" Swift moyen pour accomplir une weak
delegate
?
Vous devez vous connecter pour publier un commentaire.
Vous devez déclarer le type de protocole que
class
.Ma compréhension est que l'utilisation de
class
, vous garantie que ce protocole sera utilisé uniquement sur les classes et pas d'autres trucs comme des énumérations ou des structures.unowned
?protocol ProtocolNameDelegate: AnyObject
, mais n'a pas d'importance.AnyObject
depuisclass
sera obsolète à un certain point.Complémentaire De Réponse
J'ai toujours été confus au sujet de savoir si les délégués devraient être faible ou pas. Récemment, j'ai appris plus sur les délégués et quand utiliser les références faibles, donc permettez-moi d'ajouter quelques points supplémentaires ici pour le bénéfice des futurs spectateurs.
Le but de l'utilisation de la
weak
mot-clé est d'éviter forte des cycles de référence (conserver les cycles). Forte des cycles de référence se produire lorsque deux instances de classe ont de solides références à l'autre. Leur nombre de références ne vont jamais à zéro, de sorte qu'ils n'ont jamais désallouées.Vous avez seulement besoin d'utiliser
weak
si le délégué est une classe. Swift les structures et les énumérations sont des types de valeur (leurs valeurs sont copiées, lorsqu'une nouvelle instance est fait), pas de types de référence, afin de ne pas faire de fortes référence cycles.weak
les références sont toujours en option (sinon vous auriez utiliséunowned
) et utilisez toujoursvar
(paslet
), de sorte que l'option peut être définie ànil
quand il est libéré.D'une classe parent doit naturellement avoir une référence forte à ses enfants des classes et donc de ne pas utiliser le
weak
mot-clé. Quand un enfant veut une référence à son parent, si, il doit en faire une référence faible à l'aide de laweak
mot-clé.weak
doit être utilisé lorsque vous voulez une référence à une classe qui ne vous appartient pas, pas seulement pour un enfant de référencement de son parent. Lorsque deux non-hiérarchique des classes besoin de faire référence à chaque autre, choisissez une faiblesse. Celui que vous choisissez dépend de la situation. Voir les réponses à cette question pour en savoir plus sur cette.En règle générale, les délégués doivent être marqués comme
weak
parce que la plupart des délégués sont la référence des classes qu'ils ne possèdent pas. C'est certainement vrai quand un enfant est à l'aide d'un délégué de communiquer avec un parent. À l'aide d'une référence faible pour le délégué est ce que le la documentation recommande. (Mais voir cette, trop.)Protocoles peuvent être utilisés pour les deux les types de référence (classes) et types de valeur (structures, énumérations). Ainsi, dans le cas probable que vous avez besoin de faire un délégué de faiblesse, vous devez en faire un objet-seul protocole. La façon de le faire est d'ajouter
AnyObject
pour le protocole de la liste d'héritage. (Dans le passé vous avez fait cela à l'aide de laclass
mot-clé, maisAnyObject
est préféré maintenant.)De Poursuivre L'Étude De
Lire les articles suivants est ce qui m'a aidé à comprendre tout cela beaucoup mieux. Ils discutent également des questions connexes comme la
unowned
mot-clé et la forte cycles de référence qui se produisent avec des fermetures.Liées
AnyObject
est officiel pour l'utilisation d'une référence faible en Swift.D'Apple:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276
class
obsolète dans Swift 4.1?Mise à jour:
Il ressemble à ce manuel a été mis à jour et l'exemple que je faisais référence a été supprimée. Voir l'édition de @flainez la réponse ci-dessus.
Original:
À l'aide de @objc est la bonne façon de le faire même si vous n'êtes pas d'interopérabilité avec Obj-C. Il garantit que votre protocole est appliqué à une classe et non un enum ou structure. Voir "Vérification du Protocole de Conformité" dans le manuel.
protocole doit être sous-classe de AnyObject, classe
exemple donné ci-dessous
Apple utilise des "NSObjectProtocol" au lieu de "classe".
Cela fonctionne aussi pour moi et supprimé les erreurs que j'ai été voir lorsque essayant de mettre en place mon propre modèle de délégué.