¿Cómo declaro propiedades de nivel de clase en Objective-C?
Tal vez esto sea obvio, pero no se como declarar propiedades de clase en Objective-C.
Necesito almacenar en caché un diccionario por clase y preguntarme cómo ponerlo en la clase.
10 answers
Las propiedades tienen un significado específico en Objective-C, pero creo que quieres decir algo que es equivalente a una variable estática? Por ejemplo, ¿solo una instancia para todos los tipos de Foo?
Para declarar funciones de clase en Objective-C usa el prefijo + en lugar de - para que su implementación se vea algo así como:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-07 11:23:02
Estoy usando esta solución:
@interface Model
+ (int) value;
+ (void) setValue:(int)val;
@end
@implementation Model
static int value;
+ (int) value
{ @synchronized(self) { return value; } }
+ (void) setValue:(int)val
{ @synchronized(self) { value = val; } }
@end
Y me pareció extremadamente útil como un reemplazo del patrón Singleton.
Para usarlo, simplemente acceda a sus datos con la notación de puntos:
Model.value = 1;
NSLog(@"%d = value", Model.value);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-04 12:50:09
Como se ve en WWDC 2016 / XCode 8 ( qué hay de nuevo en la sesión LLVM @5:05). Las propiedades de clase se pueden declarar de la siguiente manera
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Tenga en cuenta que las propiedades de clase nunca se sintetizan
@implementation
static NSString * _someString
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-10 13:56:06
Si estás buscando el equivalente a nivel de clase de @property
, entonces la respuesta es "no hay tal cosa". Pero recuerde, @property
es solo azúcar sintáctica, de todos modos; solo crea métodos de objeto con nombre apropiado.
Desea crear métodos de clase que accedan a variables estáticas que, como otros han dicho, solo tienen una sintaxis ligeramente diferente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-30 05:03:15
Aquí hay una forma segura de hacerlo:
// Foo.h
@interface Foo {
}
+(NSDictionary*) dictionary;
// Foo.m
+(NSDictionary*) dictionary
{
static NSDictionary* fooDict = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
// create dict
});
return fooDict;
}
Estas ediciones aseguran que fooDict solo se cree una vez.
From Apple documentation: "dispatch_once - Ejecuta un objeto de bloque una vez y solo una vez durante la vida útil de una aplicación."
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-24 16:44:20
A partir de Xcode 8 Objective-C ahora soporta propiedades de clase:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Dado que las propiedades de la clase nunca se sintetizan, necesita escribir su propia implementación.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Se accede a las propiedades de la clase usando la sintaxis normal de punto en el nombre de la clase:
MyClass.identifier;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-14 15:11:20
Las propiedades tienen valores solo en objetos, no en clases.
Si necesita almacenar algo para todos los objetos de una clase, debe usar una variable global. Puede ocultarlo declarándolo static
en el archivo de implementación.
También puede considerar el uso de relaciones específicas entre sus objetos: atribuye un rol de maestro a un objeto específico de su clase y vincula otros objetos a este maestro. El maestro tendrá el diccionario como una propiedad simple. Pienso en un árbol como el utilizado para la jerarquía de vistas en aplicaciones Cocoa.
Otra opción es crear un objeto de una clase dedicada que se compone tanto de su diccionario 'clase' y un conjunto de todos los objetos relacionados con este diccionario. Esto es algo así como NSAutoreleasePool
en el Cacao.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-30 08:25:54
Si tiene muchas propiedades de nivel de clase, entonces un patrón singleton podría estar en orden. Algo como esto:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
Y
// Foo.m
#import "Foo.h"
@implementation Foo
static Foo *_singleton = nil;
+ (Foo *)singleton {
if (_singleton == nil) _singleton = [[Foo alloc] init];
return _singleton;
}
@synthesize property1;
@synthesize property2;
@synthesise property3;
@end
Ahora acceda a sus propiedades de nivel de clase de esta manera:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-09 07:37:01
A partir de Xcode 8, puede usar el atributo de propiedad class como respondió Berbie.
Sin embargo, en la implementación, necesita definir tanto class getter como setter para la propiedad class usando una variable estática en lugar de un iVar.
Muestra.h
@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end
Muestra.m
@implementation Sample
static Sample *_sharedSample;
+ ( Sample *)sharedSample {
if (_sharedSample==nil) {
[Sample setSharedSample:_sharedSample];
}
return _sharedSample;
}
+ (void)setSharedSample:(Sample *)sample {
_sharedSample = [[Sample alloc]init];
}
@end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-15 15:38:43
[Pruebe esta solución es simple] Puede crear una variable estática en una clase Swift y luego llamarla desde cualquier clase Objective-C.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-04 18:15:26