Answers:
属性在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
类方法内部到底意味着什么?
@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;
从Xcode 8开始,您可以使用Berbie回答的class属性属性。
但是,在实现中,您需要使用静态变量代替iVar为class属性定义类getter和setter。
样本
@interface Sample: NSObject
@property (class, retain) Sample *sharedSample;
@end
样例
@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
在这里使用a会很容易。