Aprendiendo Objective-C y leyendo código de muestra, noto que los objetos generalmente se crean usando este método:
SomeObject *myObject = [[SomeObject alloc] init];
en vez de:
SomeObject *myObject = [SomeObject new];
¿Hay alguna razón para esto, ya que he leído que son equivalentes?
objective-c
oop
willc2
fuente
fuente
Respuestas:
Aquí hay muchas razones: http://macresearch.org/difference-between-alloc-init-and-new
Algunos seleccionados son:
new
no admite inicializadores personalizados (comoinitWithString
)alloc-init
es más explícito quenew
La opinión general parece ser que debe usar lo que le resulte más cómodo.
fuente
+newWithString:
también, si ya lo implementó-initWithString
. Aunque no es tan común. Personalmente, siempre usonew
cuando el inicializador designado esinit
, muy corto y dulce.+newWithString:
. Eso rompe la separación de las preocupaciones. Sin embargo, para cuando solo quiera usarlo-init
, no hay razón para no usarlo+new
.[[NSString alloc] initWithFormat:...]
y[NSString stringWithFormat:...]
son ambos equivalentes. ¿Estás diciendo que Apple violó la separación de preocupaciones y no debería haberlo implementado de esta manera? (Nota: No estoy tratando de ser condescendiente; Me gustaría obtener más información y saber si siguiendo el ejemplo de Apple es a veces una mala idea.)Pregunta muy antigua, pero he escrito algún ejemplo solo por diversión, tal vez lo encuentre útil;)
En función principal ambas afirmaciones:
y
resultar en la misma salida:
fuente
[[InitAllocNewTest alloc] init]
no se compilará mientras[InitAllocNewTest new]
no se vea afectado. (Disculpas por la falta de saltos de línea, etc.)+new
es equivalente a+alloc/-init
en laNSObject
implementación de Apple . Es muy poco probable que esto cambie, pero dependiendo de su nivel de paranoia, la documentación de Apple+new
parece permitir un cambio de implementación (y romper la equivalencia) en el futuro. Por esta razón, porque "explícito es mejor que implícito" y para la continuidad histórica, la comunidad Objective-C generalmente evita+new
. Sin embargo, por lo general, puede detectar a los recién llegados de Java a Objective-C por su uso obstinado de+new
.fuente
+new
ha existido desde los días NeXT. Si algo+new
es una señal de alguien que aprendió objc hace mucho tiempo; Veo a muchas personas que se familiarizan con el idioma, o que incluso lo han estado escribiendo durante años, pero claramente después del boom de iOS, no tienen idea de lo que+new
significa. En segundo lugar, como+new
es muy antiguo y desde los días NeXT, Apple sería bastante loco cambiarlo de una manera que rompa el código antiguo, especialmente teniendo en cuenta que sus propias bases de código probablemente estén plagadas de él.new
idioma proviene de Smalltalk. También se usa en Ruby, y tanto Objective-C como Ruby obtienen gran parte de su sintaxis y convenciones de Smalltalk.Con frecuencia, necesitará pasar argumentos
init
y, por lo tanto, utilizará un método diferente, como[[SomeObject alloc] initWithString: @"Foo"]
. Si está acostumbrado a escribir esto, tiene el hábito de hacerlo de esta manera y, por[[SomeObject alloc] init]
lo tanto, puede ser más natural[SomeObject new]
.fuente
Una respuesta corta es:
fuente
Para una nota al margen, yo personalmente uso
[Foo new]
si quiero que se haga algo en init sin usar su valor de retorno en ningún lado. Si no utiliza la devolución de[[Foo alloc] init]
ningún lugar, recibirá una advertencia. Más o menos, lo uso[Foo new]
para dulces visuales.fuente
Llegué muy tarde a esto, pero quiero mencionar que esa nueva realidad no es segura en el mundo de Obj-C con Swift. Swift solo creará un método de inicio predeterminado si no crea ningún otro inicializador. Llamar nuevo en una clase rápida con un inicializador personalizado provocará un bloqueo. Si usa alloc / init, el compilador se quejará correctamente de que init no existe.
fuente
Si nuevo hace el trabajo por usted, también hará que su código sea un poco más pequeño. Si de lo contrario llamarías
[[SomeClass alloc] init]
a muchos lugares diferentes en su código, creará un Hot Spot en la implementación de la nueva, es decir, en el tiempo de ejecución objc, que reducirá la cantidad de errores de caché.Según tengo entendido, si necesita usar un inicializador personalizado, use
[[SomeClass alloc] initCustom]
.Si no lo haces, úsalo
[SomeClass new]
.fuente
init
función predeterminada y úsela.[[SomeClass alloc] init];
Si necesita parámetros, nunca haga algo así, hágalo[[SomeClass alloc] initWith:...];
. Por último, si anula lainit
función con una implementación personalizada, puede llamarnew
al crear un objeto, y seguirá llamando a lainit
implementación personalizada .