在Objective C中设置静态variables

我似乎无法find一种方法来设置我已经创build的静态诠释为我保存到永久内存的每个对象分配唯一的ID。 下面给我一个'没有setter方法setIdGen'的财产分配。

-(void)viewDidLoad { PlayerMenuController.idGen = [[NSUserDefaults standardUserDefaults] floatForKey:@"idGen"]; } 

除了上面我已经尝试创build一个静态setIdGen方法,将返回错误的访问错误,并使NSIntegers自己的设置方法。 当我尝试使用=,但使用setArray工作正常时,我的静态NSMutableArray给出了相同的错误。

idGen方法:

 + (int) idGen { /*static int idGen; if(!idGen) { idGen = 0; NSLog(@"idGen reset"); }*/ return self.idGen; } 

2017年更新

Xcode 8从发行说明中介绍了Objective-C的类属性:

Objective-C现在支持与Swifttypes属性互操作的类属性。 它们被声明为@property (class) NSString *someStringProperty; ,而且从不合成。

这意味着我们下面的示例界面可以变成:

 @interface PlayerMenuController : NSObject @property (class) int idGen; @end 

但是,您仍然必须自己实现这些方法,如下所示,因为类属性永远不会被合成。 请注意,这也意味着如果您指定属性属性(例如copy ),则您的方法必须实现语义。


原始答复

它看起来像你正试图实现一个类属性 ,但在Objective-C中没有这样的事情 – 一个属性是一对实例方法。

但是,你可以伪造它…

虽然@property声明不适用于你,但如果你声明遵循正确的命名约定的类方法,那么你的编译器可能会 (在Xcode 4.6.1上testing“可能”,因为我不能正确指向这个被支持的,但它很简单testing并会编译时间错误,如果不是)允许你使用点符号,即它看起来像一个类属性,即使它缺less一个@property

示例界面:

 @interface PlayerMenuController : NSObject // a class "property" + (int) idGen; + (void) setIdGen:(int)value; @end 

执行:

 @implementation PlayerMenuController static int idGen = 0; + (int) idGen { return idGen; } + (void) setIdGen:(int)value { idGen = value; } @end 

并testing它:

 NSLog(@"initial value: %d", PlayerMenuController.idGen); PlayerMenuController.idGen = 42; NSLog(@"updated value: %d", PlayerMenuController.idGen); 

生产:

 initial value: 0 updated value: 42 

所以我们有一个“阶级财产” – 它看起来,像一个财产散步和嘎嘎声;-)

如果你使用了一个静态variables,并且你想要inheritance这个variables,那么静态variables对于父类和子类都是相同的,所以当对子类进行寻址时,任何改变都会改变父类的相同“属性”。 (反之亦然)

这样做的安全方法是使用objc / runtime.h关联的对象

 +(int) idGen { NSNumber* idGen = objc_getAssociatedObject(self, @selector(idGen)); if (idGen == nil) { idGen = @0; } else { idGen = @([idGen intValue] + 1); } self.idGen = [idGen intValue]; return [idGen intValue]; } +(void)setIdGen:(int)idGen { objc_setAssociatedObject(self, @selector(idGen), @(idGen), OBJC_ASSOCIATION_RETAIN); } 

你不应该返回self.idGen因为int不是一个属性。 如果你这样做你的代码应该工作:

  + (int) idGen { static int idGen; return idGen; }