Respuestas:
Qué 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 así:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
.
sintaxis de -accessor no está vinculada a las propiedades en Objective-C, es solo un acceso directo compilado para cualquier método que devuelva algo sin tomar ningún argumento. En este caso, lo preferiría: personalmente prefiero la .
sintaxis para cualquier uso en el que el código del cliente intente obtener algo, no realizar una acción (incluso si el código de implementación puede crear algo una vez o realizar acciones de efectos secundarios) . La .
sintaxis de uso intensivo también da como resultado un código más legible: la presencia de […]
s significa que se está haciendo algo significativo cuando las recuperaciones usan la .
sintaxis en su lugar.
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 lo encontré extremadamente útil como reemplazo del patrón Singleton.
Para usarlo, simplemente acceda a sus datos con notación de puntos:
Model.value = 1;
NSLog(@"%d = value", Model.value);
self
significa dentro de un método de clase?
self
es el objeto que recibió el mensaje . Y como las clases también son objetos , en este caso self
significaModel
@synchronized
?
Como se ve en WWDC 2016 / XCode 8 ( novedades 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
static
variable ( ) aún debe declararse y usarse, y los métodos deben implementarse explícitamente, tal como estaban anteriormente. La sintaxis de puntos ya funcionaba anteriormente también. En general, esto suena como un problema mayor de lo que realmente es.
Si está buscando el equivalente a nivel de clase de @property
, entonces la respuesta es "no existe tal cosa". Pero recuerde @property
, de todos modos , es solo azúcar sintáctico; solo crea métodos de objeto con nombres apropiados.
Desea crear métodos de clase que accedan a variables estáticas que, como han dicho otros, solo tienen una sintaxis ligeramente diferente.
UIDevice.currentDevice.identifierForVendor
funciona para mi.
Aquí hay una manera 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.
De la documentación de Apple : "dispatch_once: ejecuta un objeto de bloque una vez y solo una vez durante la vida útil de una aplicación".
Initializer element is not a compile-time constant
.
A partir de Xcode 8, Objective-C ahora admite propiedades de clase:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Como las propiedades de clase nunca se sintetizan, debe escribir su propia implementación.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Accede a las propiedades de la clase utilizando la sintaxis de punto normal en el nombre de la clase:
MyClass.identifier;
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 mantendrá el diccionario como una propiedad simple. Pienso en un árbol como el que se usa para la jerarquía de vistas en las aplicaciones de Cocoa.
Otra opción es crear un objeto de una clase dedicada que esté compuesta tanto por su diccionario de 'clase' como por un conjunto de todos los objetos relacionados con este diccionario. Esto es algo así como NSAutoreleasePool
en el cacao.
A partir de Xcode 8, puede usar el atributo de propiedad de clase tal como lo respondió Berbie.
Sin embargo, en la implementación, debe definir tanto getter como setter de clase para la propiedad de clase utilizando 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
Si tiene muchas propiedades de nivel de clase, entonces podría estar en orden un patrón singleton. 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;
dispatch_once
aquí.
[Pruebe esta solución, es simple] Puede crear una variable estática en una clase Swift y luego llamarla desde cualquier clase Objective-C.