当前位置:  开发笔记 > 编程语言 > 正文

Objective C静态类级变量

如何解决《ObjectiveC静态类级变量》经验,为你挑选了5个好方法。

我有一个类电影,每个都存储一个唯一的ID.在C#,Java等中我可以定义一个静态int currentID,每次设置ID时我都可以增加currentID,并且更改发生在类级别而不是对象级别.这可以在Objective C中完成吗?我发现很难找到答案.



1> 小智..:

问题描述:

    您希望ClassA具有ClassB类变量.

    您正在使用Objective-C作为编程语言.

    Objective-C不像C++那样支持类变量.

一种选择:

使用Objective-C功能模拟类变量行为

    在classA.m中声明/定义一个静态变量,这样它只能用于classA方法(以及你放在classA.m中的所有内容).

    覆盖NSObject初始化类方法,只使用ClassB实例初始化静态变量一次.

    你会想知道,我为什么要覆盖NSObject初始化方法.有关此方法的Apple文档的答案是:"运行时在程序之前恰好一次向程序中的每个类发送初始化,或者从程序中发送任何继承自它的类,从程序中发送它的第一条消息.如果不使用该类,则永远不会被调用.)".

    随意在任何ClassA类/实例方法中使用静态变量.

代码示例:

file:classA.m

static ClassB *classVariableName = nil;

@implementation ClassA

...

+(void) initialize
{
    if (! classVariableName)
        classVariableName = [[ClassB alloc] init];
}

+(void) classMethodName
{
    [classVariableName doSomething]; 
}

-(void) instanceMethodName
{
    [classVariableName doSomething]; 
}

...

@end

参考文献:

    比较Objective-C和C++方法的类变量


@jamie,`initialize`为每个类调用一次(子类之前的超类),但如果子类不重写`initialize`,则会再次调用父类`initialize`.因此,如果您不希望代码执行两次,则需要保护.请参阅[初始化类对象](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-87244 )在Apple的Objective-C文档中.
这可能是一个愚蠢的问题,但是所述内存的释放呢?没关系,因为它必须像应用程序运行一样长寿?
如果保证initialize()只被调用一次,为什么需要条件"if(!classVariableName)"?
你能在classA.m中有一个TypeA类型的静态变量吗?

2> Gonzalo Larr..:

从Xcode 8开始,您可以在Obj-C中定义类属性.添加此项是为了与Swift的静态属性进行互操作.

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

这是一个例子

@interface YourClass : NSObject

@property (class, nonatomic, assign) NSInteger currentId;

@end

@implementation YourClass

static NSInteger _currentId = 0;

+ (NSInteger)currentId {
    return _currentId;
}

+ (void)setCurrentId:(NSInteger)newValue {
    _currentId = newValue;
}

@end

然后你可以像这样访问它:

YourClass.currentId = 1;
val = YourClass.currentId;

这是一个非常有趣的解释性帖子,我用它作为编辑这个旧答案的参考.


2011答案:(不要用这个,太可怕了)

如果你真的真的不想声明一个全局变量,还有其他选择,也许不是非常正统的:-),但是有效...你可以声明一个像这样的"get&set"方法,里面有一个静态变量:

+ (NSString*)testHolder:(NSString*)_test {
    static NSString *test;

    if(_test != nil) {
        if(test != nil)
            [test release];
        test = [_test retain];
    }

    // if(test == nil)
    //     test = @"Initialize the var here if you need to";

    return test;
}

所以,如果你需要获取值,只需调用:

NSString *testVal = [MyClass testHolder:nil]

然后,当你想要设置它时:

[MyClass testHolder:testVal]

如果您希望能够将此伪静态变量设置为nil,则可以声明testHolder为:

+ (NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {
    static NSString *test;

    if(shouldSet) {
        if(test != nil)
            [test release];
        test = [_test retain];
    }

    return test;
}

还有两个方便的方法:

+ (NSString*)test {
    return [MyClass testHolderSet:NO newValue:nil];
}

+ (void)setTest:(NSString*)_test {
    [MyClass testHolderSet:YES newValue:_test];
}

希望能帮助到你!祝好运.



3> pgb..:

在.m文件中,您可以将变量声明为static:

static ClassName *variableName = nil;

然后你可以在你的+(void)initialize方法上初始化它.

请注意,这是一个普通的C静态变量,并且在Java或C#的意义上不是静态的,但会产生类似的结果.


请更正:`+(void)initialize`是方法

4> Peter N Lewi..:

在.m文件中,声明一个文件全局变量:

static int currentID = 1;

然后在你的init例程中,参考:

- (id) init
{
    self = [super init];
    if (self != nil) {
        _myID = currentID++; // not thread safe
    }
    return self;
}

或者如果需要在其他时间更改(例如在openConnection方法中),则在那里增加它.请记住,它不是线程安全的,如果可能存在任何线程问题,您需要进行同步(或者更好,使用原子添加).



5> Tom Dalling..:

正如pgb所说,没有"类变量",只有"实例变量".做类变量的objective-c方法是类的.m文件中的静态全局变量."静态"确保变量不能在该文件之外使用(即它不能是extern).

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有