¿Por qué debo definir las variables dos veces en el file de encabezado?

¿Por qué debo definir variables dos veces en el file de encabezado? ¿Qué diferencias hay entre estas variables?

La primera definición está aquí:

@interface MyController: UIViewController { NSInteger selectedIndex; } 

La segunda definición está aquí:

 @property (nonatomic) NSInteger selectedIndex; 

Lo que está viendo era necesario en versiones anteriores de Objective-C, pero ya no lo es.

En las primeras versiones de Objective-C utilizadas por NeXT hasta que se introdujo el nuevo time de ejecución (con Objective-C 2.0 en Mac OS X), todas las variables de instancia tuvieron que declararse como parte de la estructura de la class en su @interface . La razón fue que si subclasificaba una class, el comstackdor necesitaba conocer el layout de la variable de instancia de la class para que pudiera ver en qué compensación colocar las variables de instancia de la subclass.

Cuando se introdujeron las properties, las properties sintetizadas tenían que ser "respaldadas" por una variable de instancia en la estructura de la class. Por lo tanto, tuvo que declarar una variable de instancia y la propiedad.

Todo lo anterior ya no es cierto. Newer Objective-C es less frágil en la forma en que busca compensaciones de variables de instancia, lo que ha significado algunos cambios:

  • no todas las variables de instancia deben estar en @interface . Ahora se pueden definir en @implementation : aunque no en categorías debido a las posibilidades de chocar y otros problemas.
  • Las variables de instancia para properties sintetizadas pueden inferirse y crearse en function de la definición de propiedad.
  • puede agregar variables de instancia mediante progtwigción a las classs que está creando en time de ejecución (solo antes de que haya registrado la class como disponible para el sistema).

Por lo tanto, para reiterar, solo necesita declarar tanto la variable de instancia como una propiedad sintetizada en versiones anteriores del lenguaje Objective-C. Lo que está viendo es networkingundante y no debe considerarse una "mejor práctica".

[Fuente]

Como otros han señalado, ya no es necesario declarar una variable de instancia de respaldo para una propiedad sintetizada en el encabezado.

Sin embargo, para que esto sea un poco más claro: lo que está viendo no son dos declaraciones de la misma variable, es una statement de la variable y una statement de la propiedad .

Una propiedad es básicamente un set de methods (en este caso selectedIndex y setSelectedIndex: que normalmente se usan para acceder a variables de instancia. Hay una diferencia entre una propiedad y una variable de instancia. El setter / getter de la propiedad podría hacer algo más que simplemente establecer la variable, en su ejemplo, también podría actualizar la UI para reflejar el cambio del índice seleccionado o el getter podría inferir el índice de alguna otra variable (en este caso, allí podría ser una ruta de índice de selección), etc.

Sintetizar una propiedad simplemente te libera de implementar esos methods y te proporciona implementaciones pnetworkingeterminadas que simplemente configuran la variable, pero también puedes implementar selectedIndex y setSelectedIndex: tú mismo como cualquier otro método, en cuyo caso podrías necesitar la variable de instancia en sí misma o omítalo por completo (en el caso de una propiedad inferida).

En el time de ejecución moderno, NO es necesario declararlos dos veces. Solo usa:

En ti .h

 @property (nonatomic) NSInteger selectedIndex; 

La parte entre {} es la statement del iVar. Y con su @property declara getter y setters. En el time de ejecución moderno, si utiliza el código anterior, diga básicamente lo mismo (su iVar ahora es _selectedIndex).