Pourquoi est-NSNumber immuable? Y avait-il une bonne raison? Parce que maintenant, je suis à la réflexion sur la création de ma propre classe juste pour le plaisir de la mutabilité.
Réponses
Trop de publicités?Immuable numéros d'économiser de l'espace. Supposons que votre programme crée de nombreux NSNumber
s, et la plupart d'entre eux se trouvent être des petits nombres tels que 0 ou 1. Avec immuables numéros, vous avez seulement besoin d'une poignée d'objets, un pour chaque valeur distincte. Avec mutable numéros, vous avez autant d'objets que vous avez des numéros.
Immuable numéros sont faciles à partager. Supposons que vous envelopper d'une primitive nombre (comme int
) avec un NSNumber
. Avec immuables NSNumber
, le compilateur est toujours sûr que les valeurs correspondent, de sorte qu'il peut déballer et passer la valeur primitive de la fonction que s'attendre à une valeur primitive. Avec mutable NSNumber
, vous ne pouvez pas être sûr qu'un autre thread n'a pas changer la valeur, et d'avoir à en découvre à chaque fois, ou même de penser à propos de la synchronisation. Cela devient de plus en plus coûteux si la valeur est passée de plus en plus loin dans les appels imbriqués.
Des objets immuables ont beaucoup d'autres propriétés utiles: elles sont bonnes clés de hachage, leur durée de vie et le champ d'application est plus facile à déterminer, etc. De nombreux langages fonctionnels, par exemple Erlang ou XSLT, seulement ont immuable des structures de données.
Eiko qui fait un bon point: un NSNumber représente un type de base de données et il n'a pas de sens pour le rendre mutable.
C'est comme avoir un int i=0;
et de se demander pourquoi 0 n'est pas mutable. Et dans OS X Lion x64, c'est exactement ce que pour les entiers, parce que NSNumbers sont mis en œuvre comme tagged pointeurs, qui sont des pointeurs qui contiennent des données au lieu d'une adresse.
Exemple, disons que nous voulons pour stocker le nombre entier 42 dans un pointeur. On pourrait créer un NSNumber et puis point, ou nous pourrions remplacer l'adresse 42, dans lequel cas, nous ne pouvons ignorer la création de l'objet. Mais comment pouvons-nous dire si nous avons affaire à une commune pointeur ou une tagged pointeur?
Un x86 64 pointeur a 64 bits, mais utilise seulement 48 bits pour l'adresse de pointeur. La raison en est que de 48 bits offre une 256 to d'espace d'adressage, ce qui est beaucoup. À l'aide de 64 bits serait du gaspillage, car il aurait besoin de plus de transistors dans la CPU. Ainsi, le potentiel de l'espace d'adressage 64 bits, mais les Processeurs actuels sont seulement en mesure d'utiliser 48. De ce fait, la fin de bits d'un pointeur sont 0, car ils ne sont pas utilisés. Nous utilisons ces derniers bits pour indiquer que le pointeur est une tagged pointeur qui représente un nombre entier avec un nombre donné de bits.
Par conséquent, un OS X NSNumber représentant un nombre entier est littéralement juste un nombre entier, mais l'exécution est en mesure de le détecter comme un tagged pointeur et de les présenter à l'utilisateur comme une instance commune.
Pour d'autres types numériques, la mise en œuvre est beaucoup plus complexe, comme on le voit dans le NSNumber sans frais Fondement de Base de contrepartie CFNumber.
Je pense que tout le monde avait une assez bonne réponse, sauf peut-être 9000. pas sûr de quoi il parle, mais peut-être que c'est juste au dessus de ma tête.
La décision de faire NSNumber immuable est une décision de conception par les créateurs de la Fondation de Cadre. Je pense que nous pouvons tous être d'accord sur ce point.
Je suppose que la raison pour laquelle ils n'ont que c'était parce que tous les objets instanciés en Objective-C sont référencées à l'aide de pointeurs, y compris NSNumber. Cela provoque des problèmes de conception lors du passage de NSNumber autour. Disons que vous créez une classe nommée "Personne", avec un NSNumber la propriété", myAge". Ainsi, votre application instancie une instance de la Personne et des ensembles de myAge à 28. Une autre partie de l'application, demande à la Personne de l'objet pour son âge, et elle renvoie (NSNumber*)myAge, ou un pointeur vers le NSNumber objet qui encapsule la valeur de 28. Depuis un pointeur était passé, votre Personne objet a maintenant de se demander si cette autre partie de l'application a changé la valeur de myAge!
Donc NSNumber est immuable, parce que c'est un objet destiné à contenir une valeur qui est libre d'être créé, la récupération, et passa autour de votre application en tant que valeur, pas comme unique objet.
Je suppose que c'est immuable, comme les autres classes (NSArray, NSString, etc.), parce que des objets immuables sont plus faciles à utiliser et de partager et de faire passer dans fileté code. Voir wikipedia.