Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 在Objective C中设置静态变量_Iphone_Ios_Objective C_Variables_Static - Fatal编程技术网

Iphone 在Objective C中设置静态变量

Iphone 在Objective C中设置静态变量,iphone,ios,objective-c,variables,static,Iphone,Ios,Objective C,Variables,Static,我似乎找不到一种方法来设置我创建的静态int,为保存到持久内存中的每个对象分配唯一的id。下面给出了一个“no setter方法”setIdGen,用于赋值给属性 -(void)viewDidLoad { PlayerMenuController.idGen = [[NSUserDefaults standardUserDefaults] floatForKey:@"idGen"]; } 除了上面提到的,我还尝试创建一个静态setIdGen方法,该方法将返回错误的访问错误,并使用自己的

我似乎找不到一种方法来设置我创建的静态int,为保存到持久内存中的每个对象分配唯一的id。下面给出了一个“no setter方法”setIdGen,用于赋值给属性

-(void)viewDidLoad
{
    PlayerMenuController.idGen = [[NSUserDefaults standardUserDefaults] floatForKey:@"idGen"];
}
除了上面提到的,我还尝试创建一个静态setIdGen方法,该方法将返回错误的访问错误,并使用自己的set方法创建nsinteger。当我尝试使用=分配静态NSMutableArray时,我的静态NSMutableArray给出了相同的错误,但在使用setArray时效果良好

idGen方法:

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

您不应该返回
self.idGen
,因为
int
不是属性。如果执行以下操作,您的代码应该可以工作:

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

2017年更新

Xcode 8从发行说明中向Objective-C引入了类属性:

Objective-C现在支持与Swift类型属性互操作的类属性。它们被声明为
@property(class)NSString*someStringProperty,并且永远不会被合成

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

@interface PlayerMenuController : NSObject

@property (class) int idGen;

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


原始答案

看起来您正在尝试实现一个类属性,但是Objective-C中没有这样的东西-属性是一对实例方法

然而,你可以假装它

虽然
@property
声明对您不可用,但如果您声明的类方法遵循正确的命名约定,那么您的编译器可能(在Xcode 4.6.1上测试,“可能”,因为我不能马上指出这是受支持的,但它很容易测试,如果不支持,将出现编译时错误)允许您使用点表示法,也就是说,即使缺少
@属性
,它看起来也像类属性

示例界面:

@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
并测试它:

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

initial value: 0
updated value: 42

所以我们有一个“类属性”——它看起来、走路和走路都像属性;-)

如果您使用静态变量,并且希望将其子类化,则父类和子类的静态变量都是相同的,因此在寻址子类时的任何更改也将更改其父类上的相同“属性”。(反之亦然)

安全的方法是使用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);
}

为什么你希望有一个不存在的财产存在<代码>返回idGen并取消对该块的注释。该死的,为什么我被否决的问题总是获得最多的视图:p
如果(!idGen)idGen=0是不可操作的。它是多余的不可操作之一,因为静态变量被初始化为0。是的,您可以立即初始化标量类型。只有对象需要
id obj=nil;如果(!obj)obj=[[obj alloc]init]技巧。@mipadi或任何你想延迟初始化为非零的东西。很好。我在考虑一种用法,如果标量为
nil
@H2CO3,则实例化它:何时要惰性地初始化标量?实际上,您可以声明一个属性,然后实现setter/getter方法来操作静态字段。(不建议这样做。)如果我正确地阅读了原始问题,OP将尝试使用全局变量为每个实例提供唯一的id,这当然是不可能的。@HotLicks-OP编写了“class.property”,因此我的代码。但您可能是对的,它们可能是在实例属性访问“类变量”(静态)之后。@jleher-我不同意,您可以使用静态变量为每个实例提供唯一的id。这绝非不可能,甚至不难(因为我自己也做过;-))。但是您不需要“类属性”来完成它。@Deco-全局属性应该是一个独立的并且从任何地方都可见的属性,类属性应该属于一个类,并且需要通过该类进行引用。两个不同的类可以有一个同名的类属性,但不能有两个同名的全局属性。