也许这很明显,但我不知道如何在Objective-C中声明类属性。

我需要缓存每个类的字典,不知道如何把它放在类。


当前回答

从Xcode 8开始,你可以像Berbie回答的那样使用class属性。

但是,在实现中,您需要使用静态变量代替iVar为类属性定义类getter和setter。

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

And

// 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;

从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;

属性在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;
}

如果您正在寻找类级别的@property等价物,那么答案是“不存在这样的东西”。但请记住,@property只是语法糖;它只是创建适当命名的对象方法。

您希望创建访问静态变量的类方法,正如其他人所说,这些静态变量的语法略有不同。

我使用这个解决方案:

@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);