El método alloc
asignará memoria para un objeto nuevo. Pero el método init
podría descartar esa memoria y devolver un objeto completamente diferente. O puede devolver nil
. Es por esto que siempre debe hacer self = [super init]
cuando anula un método init
.
NSString
es una clase que hace este tipo de cosas todo el tiempo.
No estoy exactamente seguro de por qué está ocurriendo la excepción, pero creo que podría ser el código de inyección de ARC entre las dos líneas de código o algo similar. Sea lo que sea, algo está tratando de actuar sobre el objeto asignado que nunca se ha inicializado, y este es un gran problema que puede conducir a todo tipo de problemas. Considérese afortunado de que haya lanzado una excepción, a veces no lo hará.
La clase NSString
podría no ser realmente una clase real. Puede contener casi ningún método y casi ninguna variable. Todo lo que tiene es un conjunto de métodos de fábrica para crear objetos de cadena "reales" de alguna otra clase, y esto se hace usando métodos como initWithFormat:
. Entonces, por una convención de larga data, alloc/init siempre debe hacerse en una sola declaración y hay un puñado de lugares donde, generalmente por razones de rendimiento, algo dependerá de que se use esta convención.
Básicamente, objetivo-c es un lenguaje en el que no necesita saber exactamente lo que está sucediendo dentro de un objeto. Solo necesita saber qué mensajes se pueden enviar a un objeto y cómo responderá. Cualquier otra cosa es un comportamiento indefinido e incluso si usted aprende cómo funciona, está sujeto a cambios sin previo aviso. A veces, el comportamiento cambiará dependiendo de circunstancias que son completamente ilógicas, por ejemplo, puede esperar que el método de "copia" le proporcione una copia del objeto al que lo envía, y aunque este es el comportamiento predeterminado, hay muchos casos en que en realidad solo devolverá el mismo objeto con banderas de administración de memoria ligeramente diferentes. Esto se debe a que la lógica interna de la clase sabe que devolver el mismo objeto es mucho más rápido y efectivamente idéntico a devolver una copia real.
Mi comprensión es copy
enviado a NSString puede devolver un objeto nuevo, o puede devolverlo. Depende de qué subclase de NSString se esté utilizando en realidad, y ni siquiera hay documentación para qué subclases existen, y mucho menos cómo se implementan.Todo lo que necesita saber es que copy
devolverá un puntero a un objeto que es perfectamente seguro de tratar como si fuera una copia aunque no lo sea.
En un lenguaje orientado a objetos "adecuado" como Objective-C, los objetos son "cajas negras" que pueden cambiar inteligentemente su comportamiento interno en cualquier momento y por cualquier motivo, pero su comportamiento externo siempre es el mismo.
Con respecto a evitar el anidamiento ... El estilo de codificación para Objective-C a menudo requiere un anidamiento extenso, o escribirás 10 líneas de código cuando solo 1 realmente se necesite. La sintaxis de corchete cuadrado es particularmente adecuada para anidar sin hacer que el código sea complicado.
Como regla general, enciendo la función "Guía de páginas en la columna" de Xcode y la configuro en 120 caracteres. Si la línea de código excede ese ancho, entonces pensaré en dividirla en varias líneas. Pero a menudo es más limpio tener una línea muy larga que tres líneas cortas.
Sé pragmático al respecto. :)
hicieron que trató la primera way..both en una línea .. solo quiero saber si funcionó .. – Shubhank
Claro - funciona como encanto con [[ClassName alloc] init] (por lo tanto, dos mensajes anidados uno detrás de otro en una línea) ... pero no estoy seguro de por qué falla la segunda. En lugar de simplemente asumir que "tiene que hacerse de esta manera", me gustaría contar con algunos consejos expertos sobre por qué se hace de esta manera. – Piotr
Esto tiene una respuesta muy interesante que lamentablemente no tengo tiempo ahora para escribir correctamente. (Creo que Abizern está dando vueltas y puede hacerle justicia). La versión ultracorta es que usted puede anidar en general, pero se permite que 'alloc' arroje el objeto que ha pasado y devuelva uno nuevo, por lo que tiene que estar anidado con 'init'. Es una convención que se ha convertido en una regla. –