2011-05-17 18 views
43

Soy nuevo en Objective C y estoy leyendo un libro llamado "Guía Visual de inicio rápido: Objective-C", de Steven Holzner, la prensa peachpitvariables de clase estática Objective C

En el Capítulo 6: Programación Orientada a Objetos, hay una la sección de nombre uso de las variables de clase en la que escribe:

puede crear variables de clase para su uso con sus clases, pero hay un problema: cada objeto de que las acciones de la clase de la misma variable, por lo si un objeto cambia de una variable de clase, esa variable se cambia para todos los objetos. Crea variables de clase con la palabra clave static. Las variables de clase son a menudo útiles: por ejemplo, puede usar una variable de clase para realizar un seguimiento de la cantidad de objetos de una clase particular creada en un programa. Lo harás en esta tarea.

y dice que introducir el siguiente código:

#import <stdio.h> 
#import <Foundation/NSObject.h> 
@interface TheClass: NSObject 
static int count; //error: cannot declare variable inside @interface or @protocol 
+(int) getCount; 
@end 
... 

Este código me da un error en Xcode 4:

No se puede declarar la variable dentro @interface o @protocol

¿El libro está equivocado o estoy haciendo algo mal?

+4

El libro es totalmente erróneo, no existe el concepto de variable de clase en Objective-C. Puede declarar variables estáticas como lo haría en C, pero no pertenecen a las clases (al menos, no semánticamente). – BoltClock

Respuesta

93

Declara la variable estática en el archivo de implementación (archivo .m). Esto debería funcionar:

// TheClass.h 
@interface TheClass : NSObject 
+ (int)count; 
@end 

// TheClass.m 
static int theCount = 0; 

@implementation TheClass 
+ (int) count { return theCount; } 
@end 

No es una variable de clase per se; Objective-C no tiene noción de una variable de clase. Sin embargo, junto con el método de clase para recuperar esta variable, funciona de manera similar a una variable de clase. Sin embargo, es realmente solo una variable estática C a la que se puede acceder mediante la implementación de la clase.

+11

¿Qué pasa si la "variable de clase" es un objeto (digamos NSSet), que requiere alguna inicialización? – Uri

+0

@mipadi - Por favor aclarar para mí. No estoy seguro de la definición de una "variable de clase" y, por lo tanto, no estoy seguro de entender por qué "no es una variable de clase". Una variable estática declarada en el archivo de implementación es compartida por todas las instancias de la clase y solo es accesible por instancias de esa clase. ¿No es una "variable de clase" porque no es accesible por subclases? ¿O hay alguna otra razón por la que haces la distinción? Sinceramente me gustaría aprender. –

+1

@ Chuck-Krutsinger Como nadie más ha respondido: el concepto de una variable de clase es el mismo que un método de clase (pero una variable), es decir, una variable a la que se puede acceder sin crear una instancia de una clase, que es exactamente variable estática en la implementación haría. La razón por la que usa el término 'variable de clase' es porque de eso se trataba la pregunta, pero no existen porque static ya proporciona la funcionalidad necesaria. –

14

He visto una guía de Visual Quickstart sobre Unix y me gustó mucho. Este no parece ser mucho mejor, al menos de la muestra. La forma correcta de crear una variable de clase en Objective-C es el siguiente:

// Counted.h 
@interface Counted : NSObject 

+ (NSUInteger) numberOfInstances; 

@end 

// Counted.m 
#import "Counted.h" 

static NSUInteger instances = 0; 

@implementation Counted 

- (id) init { 
    … 
    instances++; 
    … 
} 

- (void) dealloc { 
    instances--; 
} 

+ (NSUInteger) numberOfInstances { 
    return instances; 
} 

@end 

Ésta es, de hecho, una variable estática, no una verdadera variable de clase. Pero no deberías preocuparte demasiado por las variables de clase, generalmente son una señal de que estás haciendo algo mal. (Estoy simplificando un poco, pero no mucho).

Si está buscando un libro decente de Objective-C, lea the one by Apple. Es gratis y es una buena lectura.

6

Debe declarar la variable en el archivo .m, donde se pone @implementation. Por lo tanto,

#import "TheClass.h" 

static int count; 

@implementation 

... 

@end 

Es importante tener en cuenta que Objective-C en realidad no admite variables de clase. Pero puedes simularlos con variables estáticas, como lo estamos haciendo aquí.

9

Si la "variable de clase" necesita más de inicialización trivial, utilizar dispatch_once:

@interface Foo() 
+ (Foo *)singleton; 
@end 

+ (Foo *)singleton { 
    static Foo *_singleton; 
    static dispatch_once_t oncePredicate; 

    dispatch_once(&oncePredicate, ^{ 
     _singleton = [[Foo alloc] init]; 
    }); 

    return _singleton; 
} 
Cuestiones relacionadas