J'ai testé certaines isa swizzling avec Swift, et j'ai trouvé que cela ne fonctionne que lorsque NSObject est une super-classe (directement ou plus haut), ou en utilisant la décoration '@objc'. Sinon, il suivra un style de distribution statique et vtable, comme C ++.
Est-il normal de définir une classe Swift sans classe de base Cocoa / NSObject? Si cela me préoccupe, cela signifie renoncer à une grande partie du dynamisme d'Objective-C, comme l'interception de méthodes et l'introspection à l'exécution.
Le comportement dynamique à l'exécution est au cœur de fonctionnalités telles que les observateurs de propriétés, les données de base, la programmation orientée aspect , la messagerie d'ordre supérieur , les cadres d'analyse et de journalisation, etc.
L'utilisation du style d'appel de méthode d'Objective-C ajoute environ 20 opérandes de code machine à un appel de méthode, donc dans certaines situations ( beaucoup d'appels serrés à des méthodes avec de petits corps ), la distribution statique et vtable de style C ++ peut être meilleure.
Mais étant donné la règle générale des 95-5 ( 95% des gains de performances proviennent du réglage de 5% du code ), n'est-il pas logique de commencer par les puissantes fonctionnalités dynamiques et de les renforcer si nécessaire?
la source
Réponses:
Classes Swift qui sont des sous-classes de NSObject:
objc_msgSend()
pour les appels à (la plupart de) leurs méthodesClasses Swift qui ne sont pas des sous-classes de NSObject:
objc_msgSend()
pour les appels à leurs méthodes (par défaut)Le sous-classement de NSObject dans Swift vous offre une flexibilité d'exécution Objective-C mais également des performances Objective-C. Éviter NSObject peut améliorer les performances si vous n'avez pas besoin de la flexibilité d'Objective-C.
Éditer:
Avec Xcode 6 beta 6, l'attribut dynamique apparaît. Cela nous permet d'indiquer à Swift qu'une méthode doit utiliser la répartition dynamique et prendra donc en charge l'interception.
la source
J'ai également constaté que si je basais une classe Swift sur NSObject, je voyais un comportement d'exécution inattendu qui pouvait masquer des bogues de codage. Voici un exemple.
Dans cet exemple, où nous ne nous basons pas sur NSObject, le compilateur repère correctement l'erreur dans testIncorrect_CompilerShouldSpot, signalant "... 'MyClass' n'est pas convertible en 'MirrorDisposition'"
Dans cet exemple, où nous nous basons sur NSObject , le compilateur ne détecte pas l'erreur dans testIncorrect_CompilerShouldSpot:
Je suppose que la morale est, uniquement basée sur NSObject où vous devez vraiment le faire!
la source
Selon la référence du langage, il n'est pas nécessaire que les classes sous-classent une classe racine standard, vous pouvez donc inclure ou omettre une superclasse si nécessaire.
Notez que l'omission d'une superclasse de la déclaration de classe n'affecte pas une superclasse de base implicite de quelque sorte que ce soit. Il définit une classe de base, qui deviendra effectivement la racine d'une hiérarchie de classes indépendante.
À partir de la référence de langue:
Essayer de faire référence à
super
partir d'une classe sans super classe (c'est-à-dire une classe de base) entraînera une erreur de compilationla source
Je pense que la grande majorité des données Swift ne seront pas
objc
. Seules les parties qui doivent communiquer avec l'infrastructure de l'Objectif C seront explicitement marquées comme telles.Dans quelle mesure l'introspection d'exécution sera ajoutée au langage, je ne sais pas. L'interception de méthode ne deviendra probablement possible que si la méthode le permet explicitement. C'est mon hypothèse, mais seuls les concepteurs de langage chez Apple savent vraiment où ils se dirigent vraiment.
la source
educated guesses
dans quelques années à partir de maintenant. Mais pour le moment, ce n'est qu'un gros point d'interrogation.Ce qui suit est copié du Swift-eBook d'Apple et donne une réponse appropriée à votre question:
Définition d'une classe de base
Toute classe qui n'hérite pas d'une autre classe est appelée classe de base.
Les classes Swift n'héritent pas d'une classe de base universelle. Les classes que vous définissez sans spécifier de superclasse deviennent automatiquement des classes de base sur lesquelles vous pouvez vous appuyer.
Référence
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251la source
C'est normal. Regardez les objectifs de conception de Swift: le but est de faire disparaître d'énormes classes de problèmes de programmation. Le swizzling de méthode n'est probablement pas l'une des choses que vous voulez faire avec Swift.
la source