2009-06-04 11 views
13

He estado leyendo en RAII y construcción/inicialización de uno o dos fases. Por alguna razón, estuve en el campamento de dos fases hasta hace poco, porque en algún momento debí haber escuchado que es malo hacer operaciones propensas a errores en su constructor. Sin embargo, creo que ahora estoy convencido de que es preferible una sola fase, basada en preguntas que he leído sobre SO y otros artículos.Objeto C Construcción de dos fases de los objetos

Mi pregunta es: ¿Por qué Objective C utiliza el enfoque de dos fases (alloc/init) casi exclusivamente para constructores no convenientes? ¿Hay alguna razón específica en el lenguaje o fue solo una decisión de diseño de los diseñadores?

Respuesta

28

Tengo la envidiable situación de trabajo para el hombre que escribió +alloc en 1991, y sucedió que le hice una pregunta muy similar hace unos meses. La adición de +alloc fue para proporcionar +allocWithZone:, que era para agregar agrupaciones de memoria en NeXTSTEP 2.0 donde la memoria era muy estrecha (4M). Esto permitió a la persona que llama controlar dónde se asignaron los objetos en la memoria. Era un reemplazo para +new y su pariente, que era (y continúa siendo, aunque nadie lo usa) un constructor de una fase, basado en el new de Smalltalk. Cuando Cocoa se acercó a Apple, el uso de +alloc ya estaba afianzado, y no había vuelta atrás al +new, aunque elegir su NSZone rara vez tiene un valor significativo.

Así que no es una gran pregunta filosófica de 1 fase/2 fases. En la práctica, Cocoa tiene una construcción de fase única, porque siempre (y siempre) debe llamar a estos dos en una sola llamada sin una prueba en el +alloc. Puedes pensarlo como una forma elaborada de escribir "nuevo".

+3

+1 Guau, no podría haber pedido una mejor respuesta –

3

Mi experiencia es con C++, pero una desventaja de la inicialización de una fase de C++ es el manejo de las funciones de herencia/virtuales. En C++, you can't call virtual functions during construction or destruction (bueno, puedes, simplemente no hará lo que esperas). Un init de dos fases podría resolver esto (parcialmente. Por lo que entiendo, sería ruteado a la clase correcta, pero el init podría no haber terminado todavía. Todavía podrías hacer cosas con eso) (Todavía estoy a favor de la una fase)

Cuestiones relacionadas