2009-02-19 26 views
6

El guión bajo único en Objective-C aparentemente está reservado para el uso "interno" de Apple (y estaba disponible para su uso con variables de instancia privadas antes del reclamo de Apple). Pero ¿por qué iban a utilizar un doble -core en su ejemplo SQLiteBooks para el iPhone? Ver este fragmento tomado de MasterViewController.m:Qué es este guión bajo doble en Cocoa

+ (EditingViewController *)editingViewController { 
    // Instantiate the editing view controller if necessary. 
    if (__editingViewController == nil) { 
     __editingViewController = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]; 
    } 
    return __editingViewController; 
} 

hay mención del uso de doble subrayado en este forum lo que se refiere a C - es para el "uso interno de Compier." Supongo que no veo cómo eso es aplicable en esta situación.

Necesito un ViewController en mi aplicación que se comporte de manera similar al proyecto de ejemplo de SQLiteBooks, pero este doble subrayado me tiene perplejo.

Respuesta

20

Ni el compilador de C ni el compilador de Objective-C trata los nombres de variables con caracteres de subrayado iniciales de forma diferente a cualquier otro nombre de variable. A subrayado simple o doble líder es simplemente una convención y forma efectivamente un espacio de nombres, al igual que el prefijo NS utilizado en las clases de cacao como NSString.

Si examina el código SQLiteBooks, MasterViewController.m define esta variable global estática:

// Manage the editing view controller from this class so it can be easily accessed from both the detail and add controllers. 
static EditingViewController *__editingViewController = nil; 

así que yo creo que el autor de SQLiteBooks utiliza un subrayado doble líder para indicar una variable global.

compiladores de C (y, por extensión, Objective-C) Nombres de reserva comenzando con dos guiones bajos y una letra mayúscula para su uso por el proveedor del compilador, dándoles un espacio de nombres reservado a utilizar para las variables globales y funciones que se utilizan para implementar bibliotecas estándar, o para introducir nuevas palabras clave no estándar como __block.

Si bien el código de SQLiteBooks es técnicamente válido, en mi opinión, se confunde demasiado fácilmente con el espacio de nombres reservado. Si vuelves a usar ese código, te recomendaría cambiar el nombre de esa variable (Xcode tiene una refactorización de renombrado muy bonita que lo hará automáticamente).

+0

No puedo decir si también se aplica a C, pero en C++, se aplica un doble guión bajo para la implementación, así como un guión bajo seguido de una letra mayúscula. Eso significa que __editingViewController de hecho estaría usando un nombre que está técnicamente reservado para el proveedor del compilador. – jalf

+0

-1. \ _ \ _ o \ _A (a \ _Z) está reservado para el uso del compilador e invoca un comportamiento no definido. El * preprocesador * puede hacer lo que le dé la gana si le da un doble guión bajo. El hecho de que funcione en la mayoría de los casos no lo hace válido C. –

2

Es solo una convención de nomenclatura variable. No hace do nada. Es una forma para que los programadores se recuerden a sí mismos, "Esta es una variable privada".

+0

¿Así que está diciendo que se reemplazó el subrayado único ahora que Apple ha afirmado que para uso interno? – Meltemi

+0

esto pasa por alto el verdadero punto de la pregunta. –

+1

Sí, es la misma idea que el guión bajo simple de Apple. (Y no, Andrew, no creo haber perdido el punto. Me preguntó por qué usaban un doble guión bajo y yo expliqué). – Chuck

0

No es raro que los vendedores de compiladores/bibliotecas denoten que ciertos pre/postfixes están "reservados" para ellos. Esto es en gran parte para evitar cualquier conflicto inadvertido entre tipos/define/variables heredadas.

La publicación a la que se refiere es sobre define, no variables. Muchos compiladores utilizan doble subrayado para las definiciones que proporcionan y en las que confían.

En cuanto a por qué el código de ejemplo usa este estilo, el autor original usó el mismo estilo de codificación que probablemente emplea en su trabajo diario y nunca se resaltó el posible conflicto.

Debería estar bien conservando la muestra de código tal como está, pero si le hace sentir incómodo, puede cambiar el nombre de la variable.

+0

Cambiaría el nombre del método también a + (EditingViewController *) sharedEditingViewController {..., que es una convención de código no oficial para singletons. – Abizern

6

Para el compilador, los caracteres de subrayado se tratan como cualquier carácter alfabético. De forma más general, los guiones bajos generalmente son utilizados por extensiones de lenguaje o grandes bibliotecas para evitar conflictos con el código de usuario.

El uso de guiones bajos es problemático porque muchos grupos intentan reservar cada nombre con una combinación específica de guiones bajos.

Apple ha usado tradicionalmente un único prefijo de subrayado para denotar una variable de instancia privada (un estilo común en los lenguajes orientados a objetos). Esto se interpretó como que todos debían poner sus guiones bajo guión hasta que Apple señalara que usar un guión bajo en el código podría crear conflictos con Cocoa si Apple decide cambiar sus encabezados y tal vez no debería. Por lo tanto, los prefijos de subrayado se han convertido en una práctica de codificación "no recomendada".

En los idiomas derivados de C y C, cualquier palabra con doble guión bajo que precede y sigue es una extensión de idioma no estándar. Ver extensiones de Apple como __attribute__

guiones finales se agregan a menudo, como compilador o nombre depurador versiones destrozados de nombres originales (especialmente cuando el compilador es multi-pass) y por lo general se evitan de manera que estos nombres siguen siendo claramente distintas de las originales. Google sufijo sus variables de instancia locales Objective-C con guiones bajos para evitar conflictos con los guiones bajos de Apple.

Mi consejo: no use guiones bajos. No debería utilizar variables locales con el mismo nombre que las variables de instancia (eso es simplemente confuso). El único conflicto potencial es entre los parámetros en los métodos setter y las variables de instancia correspondientes, y probablemente debería prefijar el parámetro con una "a", "new" minúscula (o similar) ya que esto indica claramente que el parámetro es el valor entrante pero aún no es "el" valor.

+0

-1 El doble subrayado está reservado para ser utilizado por "la implementación", es decir, preprocesador/compilador/bibliotecas e invoca un comportamiento indefinido a menos que se especifique lo contrario, según el C99. No significan "extensión no estándar", p. \ _ \ _ FILE \ _ \ _, \ _ \ _ LINE \ _ \ _, \ _ \ _ func \ _ \ _. Para obtener más detalles, consulte http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf –

Cuestiones relacionadas