Question

Ayant récemment fait un certain développement pour iPhone, je suis venu à remarquer un modèle de design intéressant beaucoup utilisé dans l'iPhone SDK, en ce qui concerne la mutabilité objet.

Il semble que l'approche typique, il est de définir une NSFoo de classe immuable, et d'en tirer alors de lui un NSMutableFoo descendant mutable. En règle générale, les membres de la classe données définit de NSFoo, getters et opérations en lecture seule, et la NSMutableFoo dérivée ajoute le setters et les opérations modificatrices.

Être plus familier avec C ++, je ne pouvais pas empêcher de remarquer que cela semble être un contraire à ce que je ferais en écrivant le même code en C ++. Alors que vous avez certainement peut adopter cette approche, il me semble qu'une approche plus concise est de créer une seule classe Foo, apporteurs de marque et les opérations en lecture seule en tant que fonctions const, et aussi mettre en œuvre les opérations mutables et setters dans la même classe. Vous pouvez ensuite finir avec une classe mutable, mais les types Foo const*, Foo const& etc tous sont effectivement l'équivalent immuable.

Je suppose que ma question est, est-ce mon avis sur le sens de faire de la situation? Je comprends pourquoi fait les choses différemment Objective-C, mais sont-il des avantages à l'approche à deux classes en C ++ que je l'ai manqué? Ou suis-je manque le point tout à fait?

Pas une question trop grave -. Plus pour ma propre curiosité qu'autre chose

Était-ce utile?

La solution

Objective-C est trop dynamique. En C de const-qualification est appliquée au moment de la compilation, et toute violation de const-qualification à l'exécution (tels que la modification d'un objet const qualifié par un pointeur non-const qualifié) est un comportement non défini.

Il est en partie la même que la raison pour laquelle il n'y a pas de méthodes privées en Objective-C. Vous êtes libre d'envoyer le message que vous voulez tout objet. L'envoi d'exécution prend un objet et un message, et résout une implémentation de la méthode à appeler.

si const objets qualifiés ne pouvaient invoquer des méthodes de const qualifiés, il serait complètement ruiner la nature dynamique de l'Objective-C et la Fondation parce que vérification de ce devrait être fait lors de l'exécution (première vérification déterminera si envoyé le message décide de une mise en œuvre de const qualifié pour cette instance spécifique, et un autre contrôle pour déterminer si l'instance elle-même était const-qualifié). Considérons cet exemple théorique:

NSArray *mutableArray = [[NSArray alloc] init];

NSString *mutableString = @"I am a mutable string";
const NSString *immutableString = @"I am immutable because I am const-qual'd";

[mutableArray addObject:mutableString];
[mutableArray addObject:immutableString]; // what happens?!

// and what happens here (both immutable and mutable strings would respond
// to the same selectors because they are the same class):
[mutableArray makeObjectsPerformSelector:@selector(aMutableOperation)];

Tout à coup, vous perdez la dynamique. Comme il est maintenant, les objets mutables et immuables peuvent s'asseoir ensemble dans une collection immuable ou mutable.

Avoir une sous-classe mutable conserve la nature dynamique de l'Objective-C et maintient la simple exécution. Il y avait un sujet similaire il y a quelques temps sur les méthodes privées.

Autres conseils

Pensées ...

Mac, comme vous le savez, en C ++, vous pouvez penser à "A" et "const A" comme deux types différents, avec leurs seules relations étant

  1. "A" et "A &" peut être implicitement à "const A" et "const A &", etc ...
  2. "const A &" peut être const_cast à "A &", etc ...

Les poignées de compilateur de succession et la propagation du type de modification à travers les expressions, etc.

Je suppose que les gens ont choisi le NS ..Mutable .. convention pour plusieurs raisons. Ma première hypothèse est que je crois que lorsque NextStep était à l'origine un pionnier, C n'a pas le soutien de « const » et il ne fonctionne toujours pas orienté objet. Et plus important encore, ils voulaient certaines optimisations dans leurs implémentations mutable vs objet immuable. Par exemple, dans une classe de chaîne immuable comme NSString, il peut être utile de chaînes « piscine ». Cela permet de chaînes en double à atomiser et pour le processus d'utiliser potentiellement moins de mémoire. (Il a certains inconvénients, mais il y a toujours des compromis.)

En C ++ vous pouvez diriger dans la même direction en première compréhension copy-on-write . std :: string est dit de le faire.

Sujet intéressant,
Will Bradley

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top