objective-c class-extensions

objective c - Extensión de clase Objective-C



class-extensions (5)

La diferencia principal entre categorías y extensiones es que la extensión espera que implemente los métodos dentro de su implementación principal, mientras que con una categoría, puede estar en otra implementación. También parece que las personas están usando extensiones principalmente para métodos privados.

Correcto.

¿Cuál es la diferencia entre utilizar una extensión de clase para declarar un método privado y no declararlo en absoluto (parece compilar en ejecución en ambos casos)?

Tal vez solo una advertencia del compilador con respecto al selector no declarado. (Por supuesto, funciona bien: el método está implementado y existe.) También tenga en cuenta que una declaración (una firma de función correcta y conocida) es necesaria para que el compilador emita un código binario correcto conforme a ABI. La suposición que hace sobre los métodos no declarados (a saber, que devuelven id y aceptan argumentos variados) puede no ser correcta: llamar a una función mediante un puntero de un tipo incompatible es un comportamiento indefinido.

¿Cuál es la diferencia entre declarar ivars dentro de la extensión y declararla directamente dentro de la implementación?

En el 4to ejemplo, es una variable C global, no es una variable de instancia de su clase.

¿Cuándo debería poner un guión bajo (_) delante del nombre de una variable?

Siempre que lo desee, solo hágalo de manera consistente. Siempre o nunca

Como un programador objetivo-c bastante nuevo (con una experiencia de Java de 4 años), parece que me cuesta entender cuándo usar las extensiones de clase. Por lo que entendí (y por favor, corríjanme si estoy equivocado), la diferencia principal entre categorías y extensiones es que la extensión espera que implemente los métodos dentro de su implementación principal, mientras que con una categoría, puede estar en otra implementación . También parece que las personas están usando extensiones principalmente para métodos privados.

Esta es mi primera pregunta. ¿Cuál es la diferencia entre utilizar una extensión de clase para declarar un método privado y no declararlo en absoluto (parece compilar en ejecución en ambos casos)? (ejemplo 1 vs 2)

Ejemplo 1

@interface Class() -(void) bar; @end @implementation Class -(void) foo { [self bar]; } -(void) bar { NSLog(@"bar"); } @end

Ejemplo 2

@implementation Class -(void) foo { [self bar]; } -(void) bar { NSLog(@"bar"); } @end

Segunda pregunta: ¿Cuál es la diferencia entre declarar ivars dentro de la extensión y declararla directamente dentro de la implementación? (Ejemplo 3 vs 4)

Ejemplo 3

@interface Class() { NSArray *mySortedArray; } @end @implementation Class @end

Ejemplo 4

@implementation Class NSArray *mySortedArray; @end

Tengo una última pregunta sobre las convenciones de codificación: ¿cuándo debería poner un guión bajo (_) delante del nombre de una variable?

Gracias


En la pregunta 1, ejemplo 2: los métodos foo y bar implementados en Class son visibles para las instancias de Class. Si foo y bar no están declarados en un archivo de encabezado separado Y el archivo de implementación no está disponible, otra clase ignorará la existencia de foo y bar. foo y bar son métodos privados; las instancias de Clase seguirán respondiendo a los mensajes foo y bar. Además, Xcode marcará una advertencia si otra clase que intenta enviar mensajes a foo y a una barra ya que Xcode no puede verificar (sin la declaración en el archivo de encabezado) que existen foo y barra. Por el contrario, la declaración de barra del ejemplo 1 permite a cualquier otra clase enviar una barra de mensajes a instancias de clase. Xcode tampoco marcará un error para cualquier mensaje a bar si @interface Class está en un archivo de encabezado que es #import por la otra clase.

En la pregunta 2, ejemplo 4: mySortedArray es una matriz inmutable local declarada con alcance local dentro de Class. MySortedArray en el ejemplo 3 es una variable de instancia de tipo NSArray accesible para otra clase que crea una instancia de clase.




Métodos en extensiones de clase

Nunca solía ser el caso de que no necesitara declarar sus métodos privados. Hasta hace poco, necesitabas declarar tus métodos privados en alguna parte, y la mayoría de las personas eligen una extensión de clase para hacerlo. Desde Xcode 4.4 (creo), el compilador es lo suficientemente inteligente como para determinar qué métodos deben ser privados dentro de esa implementación, eliminando la necesidad de declararlos en otro lugar.

Variables en extensiones de clase

En cuanto a los ejemplos 3 y 4, ten cuidado. Dentro de una extensión de clase, la variable es una variable de instancia para esa clase (ejemplo 3). El ejemplo 4 declara una variable global (debido a que sigue la semántica de la variable global desde C). Sigue con el ejemplo 3 para tus variables de instancia privadas.

Convenciones de codificación

En cuanto a la convención de codificación, depende del desarrollador / equipo decidir si usar un guión bajo o no. Nuestro equipo usa m_ para variables de instancia privadas. Apple en su documentación sugiere usar guiones bajos (ese es el estilo de denominación para las variables de instancia subyacentes para las propiedades sintetizadas). Lo importante es ser coherente en todo tu código.