Ответы:
свойства имеют конкретное значение в Objective-C, но я думаю, что вы имеете в виду нечто, эквивалентное статической переменной? Например, только один экземпляр для всех типов Foo?
Чтобы объявить функции класса в Objective-C, вы используете вместо + префикс +, поэтому ваша реализация будет выглядеть примерно так:
// Foo.h
@interface Foo {
}
+ (NSDictionary *)dictionary;
// Foo.m
+ (NSDictionary *)dictionary {
static NSDictionary *fooDict = nil;
if (fooDict == nil) {
// create dict
}
return fooDict;
}
.Синтаксис -accessor не привязан к свойствам в Objective-C, это просто скомпилированный ярлык для любого метода , который возвращает то , что без принятия какого - либо арга. В этом случае я бы предпочел это - я лично предпочитаю .синтаксис для любого использования, когда код клиента намеревается получить что-то, а не выполнить действие (даже если код реализации может создать что-то один раз или выполнить побочные действия) . .Синтаксис интенсивного использования также приводит к более читабельному коду: присутствие […]s означает, что происходит что-то существенное, когда выборки используют .вместо этого синтаксис.
Я использую это решение:
@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
И я нашел это чрезвычайно полезным в качестве замены шаблона Singleton.
Чтобы использовать его, просто получите доступ к своим данным с точечной нотацией:
Model.value = 1;
NSLog(@"%d = value", Model.value);
selfозначает внутри метода класса?
self- это объект, который получил сообщение . И поскольку классы также являются объектами , в данном случае это selfозначаетModel
@synchronized?
Как видно из WWDC 2016 / XCode 8 ( что нового в сессии LLVM @ 5: 05). Свойства класса могут быть объявлены следующим образом
@interface MyType : NSObject
@property (class) NSString *someString;
@end
NSLog(@"format string %@", MyType.someString);
Обратите внимание, что свойства класса никогда не синтезируются
@implementation
static NSString * _someString;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
staticпеременная ( ) все равно должна быть объявлена и использована, а методы должны быть реализованы явно, как и прежде. Синтаксис точек уже работал и раньше. В целом, это звучит как нечто большее, чем на самом деле.
Если вы ищете эквивалент класса @property, то ответ «такого нет». Но помните @property, в любом случае это только синтаксический сахар; он просто создает методы объекта с соответствующим именем.
Вы хотите создать методы класса, которые обращаются к статическим переменным, которые, как уже говорили другие, имеют только немного другой синтаксис.
UIDevice.currentDevice.identifierForVendorработает для меня.
Вот потокобезопасный способ сделать это:
// 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;
}
Эти изменения гарантируют, что fooDict создается только один раз.
Из документации Apple : «dispatch_once - выполняет объект блока один раз и только один раз за время существования приложения».
Initializer element is not a compile-time constant.
Начиная с Xcode 8 Objective-C теперь поддерживает свойства класса:
@interface MyClass : NSObject
@property (class, nonatomic, assign, readonly) NSUUID* identifier;
@end
Поскольку свойства класса никогда не синтезируются, вам нужно написать собственную реализацию.
@implementation MyClass
static NSUUID*_identifier = nil;
+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
}
@end
Вы получаете доступ к свойствам класса, используя обычный синтаксис точки на имени класса:
MyClass.identifier;
Свойства имеют значения только в объектах, а не в классах.
Если вам нужно что-то хранить для всех объектов класса, вы должны использовать глобальную переменную. Вы можете скрыть это, объявив это staticв файле реализации.
Вы также можете рассмотреть возможность использования определенных отношений между вашими объектами: вы приписываете роль мастера определенному объекту вашего класса и связываете другие объекты с этим мастером. Мастер будет содержать словарь как простое свойство. Я думаю о дереве, подобном тому, которое используется для иерархии представления в приложениях Какао.
Другой вариант - создать объект выделенного класса, который состоит из вашего словаря 'class' и набора всех объектов, связанных с этим словарем. Это что-то вроде NSAutoreleasePoolкакао.
Начиная с Xcode 8, вы можете использовать атрибут свойства класса в ответе Берби.
Однако в реализации вам необходимо определить и класс getter, и сеттер для свойства класса, используя статическую переменную вместо 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
Если у вас много свойств уровня класса, то может быть в порядке одноэлементный шаблон. Что-то вроде этого:
// Foo.h
@interface Foo
+ (Foo *)singleton;
@property 1 ...
@property 2 ...
@property 3 ...
@end
И
// 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
Теперь получите доступ к своим свойствам на уровне класса, как это:
[Foo singleton].property1 = value;
value = [Foo singleton].property2;
dispatch_onceздесь.
[Попробуйте это решение, это просто] Вы можете создать статическую переменную в классе Swift, а затем вызвать ее из любого класса Objective-C.