Respostas:
propriedades têm um significado específico em Objective-C, mas acho que você quer dizer algo equivalente a uma variável estática? Por exemplo, apenas uma instância para todos os tipos de Foo?
Para declarar funções de classe no Objective-C, use o prefixo + em vez de - para que sua implementação se pareça com:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
.
sintaxe -accessor não está vinculada a propriedades no Objective-C, é apenas um atalho compilado para qualquer método que retorna algo sem aceitar argumentos. Nesse caso, eu preferiria - eu pessoalmente prefiro a .
sintaxe para qualquer uso em que o código do cliente pretenda obter algo, não execute uma ação (mesmo que o código de implementação possa criar algo uma vez ou executar ações de efeito colateral) . A .
sintaxe de uso intenso também resulta em código mais legível: a presença de […]
s significa que algo significativo está sendo feito quando as buscas usam a .
sintaxe.
Estou usando esta solução:
@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
E eu achei extremamente útil como uma substituição do padrão Singleton.
Para usá-lo, basta acessar seus dados com notação de ponto:
Model.value = 1;
NSLog(@"%d = value", Model.value);
self
significa dentro de um método de classe?
self
é o objeto que recebeu a mensagem . E uma vez que as aulas são também objetos , neste caso self
meiosModel
@synchronized
?
Como visto na WWDC 2016 / XCode 8 (o que há de novo na sessão do LLVM às 05:00 ). Propriedades da classe podem ser declaradas da seguinte maneira
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Observe que as propriedades da classe nunca são sintetizadas
@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
static
variável ( ) ainda deve ser declarada e usada, e os métodos implementados explicitamente, exatamente como eram anteriormente. A sintaxe de pontos também já funcionou anteriormente. Ao todo, isso parece um negócio maior do que realmente é.
Se você está procurando o equivalente a nível de classe @property
, a resposta é "não existe". Mas lembre-se, @property
é apenas açúcar sintático, de qualquer maneira; apenas cria métodos de objeto com nome apropriado.
Você deseja criar métodos de classe que acessem variáveis estáticas que, como outros já disseram, têm apenas uma sintaxe ligeiramente diferente.
UIDevice.currentDevice.identifierForVendor
funciona para mim.
Aqui está uma maneira segura de fazer isso:
// 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;
}
Essas edições garantem que fooDict seja criado apenas uma vez.
Na documentação da Apple : "dispatch_once - executa um objeto de bloco uma vez e apenas uma vez durante a vida útil de um aplicativo".
Initializer element is not a compile-time constant
.
A partir do Xcode 8, o Objective-C agora suporta propriedades de classe:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Como as propriedades da classe nunca são sintetizadas, você precisa escrever sua própria implementação.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Você acessa as propriedades da classe usando a sintaxe de ponto normal no nome da classe:
MyClass.identifier;
Propriedades têm valores apenas em objetos, não em classes.
Se você precisar armazenar algo para todos os objetos de uma classe, precisará usar uma variável global. Você pode ocultá-lo declarando-o static
no arquivo de implementação.
Você também pode considerar o uso de relações específicas entre seus objetos: atribui uma função de mestre a um objeto específico da sua classe e vincula outros objetos a esse mestre. O mestre manterá o dicionário como uma propriedade simples. Penso em uma árvore como a usada para a hierarquia de exibição nos aplicativos de cacau.
Outra opção é criar um objeto de uma classe dedicada composta pelo dicionário da 'classe' e por um conjunto de todos os objetos relacionados a este dicionário. Isso é algo como NSAutoreleasePool
no cacau.
A partir do Xcode 8, você pode usar o atributo de propriedade de classe conforme respondido por Berbie.
No entanto, na implementação, você precisa definir o getter e o setter de classe para a propriedade de classe usando uma variável estática no lugar de um iVar.
Sample.h
@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end
Sample.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
Se você tiver muitas propriedades no nível de classe, um padrão singleton poderá estar em ordem. Algo assim:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
E
// 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
Agora acesse suas propriedades em nível de classe como esta:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
dispatch_once
aqui.
[Tente esta solução, é simples] Você pode criar uma variável estática em uma classe Swift e chamá-la de qualquer classe Objective-C.