Tengo una película de clase, cada una de las cuales almacena una identificación única. En C #, Java, etc., puedo definir un int currentID estático y cada vez que configuro el ID puedo aumentar el currentID y el cambio se produce a nivel de clase, no a nivel de objeto. ¿Se puede hacer esto en Objective-C? Me ha resultado muy difícil encontrar una respuesta para esto.
Desea que su ClassA tenga una variable de clase ClassB.
Estás utilizando Objective-C como lenguaje de programación.
Objective-C no admite variables de clase como lo hace C ++.
Una alternativa :
Simule un comportamiento variable de clase utilizando las características de Objective-C
Declare / defina una variable estática dentro de la clase A.M para que solo sea accesible para los métodos de la clase A (y todo lo que ponga dentro de la clase A.)
Sobrescriba el método de clase de inicialización NSObject para inicializar solo una vez la variable estática con una instancia de ClassB.
Te preguntarás, ¿por qué debería sobrescribir el método de inicialización NSObject? La documentación de Apple sobre este método tiene la respuesta: "El tiempo de ejecución envía la inicialización a cada clase en un programa exactamente una vez justo antes de que la clase, o cualquier clase que herede de ella, reciba su primer mensaje desde el programa. (Por lo tanto, el método nunca se puede invocar si no se usa la clase.) ".
Siéntase libre de usar la variable estática dentro de cualquier método de clase / instancia de ClassA.
¿Puedes tener una variable estática de Tipo ClassA dentro de classA.m?
Goatlinks
66
Esta podría ser una pregunta tonta, pero ¿qué pasa con la liberación de dicho recuerdo? no importa porque tiene que vivir mientras la aplicación se esté ejecutando?
samiq
1
@samiq, mira Objective-C: ¿Por qué retener una variable estática? . El puntero al objeto no se puede eliminar, pero el objeto en sí sí. Probablemente no desee liberarlo porque lo más probable es que lo desee durante todo el tiempo que la aplicación se esté ejecutando, pero ahorrará memoria si lo libera, por lo que si sabe que ya no lo necesita, entonces debería liberarlo.
ma11hew28
55
Si se garantiza que invocar initialize () solo una vez, ¿por qué necesita el condicional "if (! ClassVariableName)"?
jb
23
@jamie, initializese llama una vez para cada clase (superclases antes de las subclases), pero si una subclase no se anula initialize, initializese llamará nuevamente a la clase principal . Por lo tanto, se requiere una protección si no desea que el código se ejecute dos veces. Consulte Inicializar un objeto de clase en los documentos Objective-C de Apple.
big_m
31
A partir de Xcode 8, puede definir propiedades de clase en Obj-C. Esto se ha agregado para interoperar con las propiedades estáticas de Swift.
Objective-C ahora admite propiedades de clase, que interoperan con las propiedades de tipo Swift. Se declaran como: @property (class) NSString * someStringProperty ;. Nunca se sintetizan. (23891898)
Aquí hay una publicación explicativa muy interesante que utilicé como referencia para editar esta vieja respuesta.
Respuesta 2011: (no uses esto, es terrible)
Si realmente no quiere declarar una variable global, hay otra opción, quizás no muy ortodoxa :-), pero funciona ... Puede declarar un método "get & set" como este, con una variable estática dentro:
+(NSString*)testHolder:(NSString*)_test {staticNSString*test;if(_test != nil){if(test != nil)[test release];
test =[_test retain];}// if(test == nil)// test = @"Initialize the var here if you need to";return test;}
Entonces, si necesita obtener el valor, simplemente llame:
NSString*testVal =[MyClass testHolder:nil]
Y luego, cuando quieras configurarlo:
[MyClass testHolder:testVal]
En el caso de que desee poder establecer este pseudo-static-var en nil, puede declarar testHolderasí:
+(NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {staticNSString*test;if(shouldSet){if(test != nil)[test release];
test =[_test retain];}return test;}
Genial, pero no es realmente una variable global porque no se puede acceder desde otros .marchivos, y creo que está bien que sea "global" dentro del Class.marchivo.
ma11hew28
29
En su archivo .m, puede declarar una variable como estática:
staticClassName*variableName = nil;
Luego puede inicializarlo en su +(void)initializemétodo.
Tenga en cuenta que esta es una variable estática de C simple y no es estática en el sentido de que Java o C # lo consideren, pero producirán resultados similares.
o si necesita cambiar en otro momento (por ejemplo, en su método openConnection), increméntelo allí. Recuerde que no es seguro para subprocesos como es, deberá hacer una sincronización (o mejor aún, usar un agregado atómico) si puede haber algún problema de subprocesamiento.
Como dijo pgb, no hay "variables de clase", solo "variables de instancia". La forma objetiva-c de hacer variables de clase es una variable global estática dentro del archivo .m de la clase. El "estático" asegura que la variable no se pueda usar fuera de ese archivo (es decir, no puede ser externa).
(Estrictamente hablando, no es una respuesta a la pregunta, pero en mi experiencia probablemente sea útil al buscar variables de clase)
Un método de clase a menudo puede desempeñar muchos de los roles que una variable de clase desempeñaría en otros idiomas (por ejemplo, configuración cambiada durante las pruebas):
Ahora, un objeto de clase MyClsllama Resource:changeSomething:con la cadena @"Something general"a una llamada a doTheThing:, pero un objeto derivado de MySpecialCasecon la cadena @"Something specific".
initialize
se llama una vez para cada clase (superclases antes de las subclases), pero si una subclase no se anulainitialize
,initialize
se llamará nuevamente a la clase principal . Por lo tanto, se requiere una protección si no desea que el código se ejecute dos veces. Consulte Inicializar un objeto de clase en los documentos Objective-C de Apple.A partir de Xcode 8, puede definir propiedades de clase en Obj-C. Esto se ha agregado para interoperar con las propiedades estáticas de Swift.
Aquí hay un ejemplo
Entonces puedes acceder de esta manera:
Aquí hay una publicación explicativa muy interesante que utilicé como referencia para editar esta vieja respuesta.
Respuesta 2011: (no uses esto, es terrible)
Si realmente no quiere declarar una variable global, hay otra opción, quizás no muy ortodoxa :-), pero funciona ... Puede declarar un método "get & set" como este, con una variable estática dentro:
Entonces, si necesita obtener el valor, simplemente llame:
Y luego, cuando quieras configurarlo:
En el caso de que desee poder establecer este pseudo-static-var en nil, puede declarar
testHolder
así:Y dos métodos útiles:
¡Espero eso ayude! Buena suerte.
fuente
.m
archivos, y creo que está bien que sea "global" dentro delClass.m
archivo.En su archivo .m, puede declarar una variable como estática:
Luego puede inicializarlo en su
+(void)initialize
método.Tenga en cuenta que esta es una variable estática de C simple y no es estática en el sentido de que Java o C # lo consideren, pero producirán resultados similares.
fuente
En su archivo .m, declare una variable global de archivo:
luego, en su rutina de inicio, haga referencia a que:
o si necesita cambiar en otro momento (por ejemplo, en su método openConnection), increméntelo allí. Recuerde que no es seguro para subprocesos como es, deberá hacer una sincronización (o mejor aún, usar un agregado atómico) si puede haber algún problema de subprocesamiento.
fuente
Como dijo pgb, no hay "variables de clase", solo "variables de instancia". La forma objetiva-c de hacer variables de clase es una variable global estática dentro del archivo .m de la clase. El "estático" asegura que la variable no se pueda usar fuera de ese archivo (es decir, no puede ser externa).
fuente
Aquí sería una opción:
Tenga en cuenta que este método será el único método para acceder a la identificación, por lo que deberá actualizarlo de alguna manera en este código.
fuente
(Estrictamente hablando, no es una respuesta a la pregunta, pero en mi experiencia probablemente sea útil al buscar variables de clase)
Un método de clase a menudo puede desempeñar muchos de los roles que una variable de clase desempeñaría en otros idiomas (por ejemplo, configuración cambiada durante las pruebas):
Ahora, un objeto de clase
MyCls
llamaResource:changeSomething:
con la cadena@"Something general"
a una llamada adoTheThing:
, pero un objeto derivado deMySpecialCase
con la cadena@"Something specific"
.fuente
Puede cambiar el nombre de la clase como classA.mm y agregarle funciones de C ++.
fuente
Otra posibilidad sería tener una pequeña
NSNumber
subclase singleton.fuente