Pregunta

Una vez hecho recientemente algún desarrollo para iPhone, he llegado a notar un patrón de diseño interesante utiliza mucho en el iPhone SDK, con respecto a la mutabilidad objeto.

Parece que el enfoque típico que hay que definir una clase NSFoo inmutable, y luego derivar de ella un descendiente NSMutableFoo mutable. En general, los define los clase NSFoo datos miembros, getters y operaciones de sólo lectura, y el NSMutableFoo derivado añade en incubadoras y operaciones mutantes.

Al ser más familiarizados con C ++, no pude dejar de notar que este parece ser un todo lo contrario a lo que haría al escribir el mismo código en C ++. Aunque es cierto que podría adoptar ese enfoque, me parece que un enfoque más concisa es crear una única clase Foo, captadores de marca y las operaciones de sólo lectura como funciones const, y también implementar las operaciones mutables y setters en la misma clase. A continuación, terminar con una clase mutable, pero los tipos Foo const*, Foo const& etc todos son efectivamente el equivalente inmutable.

Creo que mi pregunta es, ¿mi toma en el sentido situación de maquillaje? Entiendo por qué Objective-C hace las cosas de manera diferente, pero ¿Hay alguna ventaja en el enfoque de dos clases en C ++ que me he perdido? O me estoy perdiendo totalmente el punto?

No es una cuestión demasiado serio -. Más por mi propia curiosidad que otra cosa

¿Fue útil?

Solución

Objetivo-C es demasiado dinámico. En C ++ const-calificación se aplica en tiempo de compilación, y cualquier violaciónes de const-calificación en tiempo de ejecución (por ejemplo, la modificación de un objeto const calificados a través de un puntero no const-calificado) es un comportamiento indefinido.

Es en parte la misma que la razón por la cual no existen métodos particulares en Objective-C. Usted es libre de enviar cualquier mensaje que desee a cualquier objeto. El envío en tiempo de ejecución toma un objeto y un mensaje, y resuelve una implementación del método a invocar.

Si const objetos calificados sólo podían invocar métodos calificados const, arruinaría por completo la naturaleza dinámica de Objective-C y la Fundación porque tendría que ser hecho en tiempo de ejecución de un control de este tipo (primer cheque sería determinar si el mensaje se envía resuelve una implementación const cualificado para ese caso específico y en otra comprobación para determinar si la instancia en sí era const cualificado). Considere este ejemplo teórico:

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)];

De repente se pierde la dinámica. Como está ahora, los objetos mutables e inmutables pueden sentarse juntos en una colección inmutables o mutables.

Tener una subclase mutable mantiene el carácter dinámico de Objective-C y mantiene el tiempo de ejecución sencilla. Hubo un tema similar hace un tiempo acerca de los métodos privados.

Otros consejos

Pensamientos ...

Mac, como usted sabe, en C ++, se puede pensar en "A" y "una constante" como dos tipos diferentes, siendo sus únicas relaciones

  1. "A" y "A &" se puede convertir implícitamente a "una constante" y "A const &", etc ...
  2. "const A &" puede ser const_cast a "A &", etc ...

Las asas compilador la herencia y de propagación del tipo de modificador a través de expresiones, etc.

Me imagino que la gente NS eligieron el ..Mutable .. convención por un par de razones. Mi primera suposición es que yo creo que cuando NextStep estaba siendo pionero en un principio, C no tiene soporte para "const" y que todavía no tiene orientación a objetos. Y lo más importante, que querían ciertas optimizaciones en sus vs. mutable implementación de los objetos inmutables. Por ejemplo, en una clase de cadena inmutable como NSString, puede ser útil para cuerdas "pool". Esto permite que las cadenas duplicadas a atomizar y para el proceso de usar potencialmente menos memoria. (Tiene ciertas desventajas, pero siempre hay ventajas y desventajas.)

En C ++ puede dirigirse en la misma dirección por primera comprensión copia en escritura . std :: string se dice que hacer esto.

tema interesante, España Bradley

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top