也许这很明显,但我不知道如何在Objective-C中声明类属性.
我需要为每个类缓存一个字典,并想知道如何将它放入类中.
属性在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; }
我正在使用这个解决方案:
@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);
如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
如果你正在寻找等级的等级@property
,那么答案就是"没有这样的东西".但请记住@property
,无论如何,它只是语法糖; 它只是创建适当命名的对象方法.
您想要创建访问静态变量的类方法,正如其他人所说的那样,静态变量的语法略有不同.
这是一种线程安全的方法:
// 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 - 在应用程序的生命周期内执行一次且仅执行一次块对象."
从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
在实现文件中声明它来隐藏它.
您还可以考虑使用对象之间的特定关系:将master的角色归因于类的特定对象,并将其他对象链接到此master.主人将字典作为一个简单的属性.我想到的树就像Cocoa应用程序中用于视图层次结构的树.
另一种选择是创建一个专用类的对象,该对象由"类"字典和与该字典相关的所有对象组成.这就像NSAutoreleasePool
在Cocoa中.
从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