在Objective-C中初始化静态变量

时间:2012-08-28 13:26:05

标签: objective-c idioms

在Objective-C类中,我想只将文本文件的内容加载到NSString中,以便该类的所有实例都可以使用它。

在Java世界中,我多年来了解到,如果你不使用经过验证的成语,就很容易在线程安全方面出现这种错误。所以我想确保使用正确的习语。

你能告诉我一个Objective-C类的例子吗?

这是我开始的空课......

@interface TestClass : NSObject
- (NSString *)doSomething:(NSUInteger)aParam;
@end

@implementation TestClass {
}

- (id)init {
    self = [super init];
    if (self) {

    }
    return self;
}

- (NSString *)doSomething:(NSUInteger)aParam {
     // something with shared NSString loaded from text file, 
     //  depending on the value of aParam
     return @""; 
}
@end

4 个答案:

答案 0 :(得分:7)

在Objective C中处理静态属性的惯用方法是将它们隐藏在类方法(具有+的方法)之后。在类方法的实现中将您的字符串声明为static,并使用dispatch_once进行初始化:

+ (id)stringFromFile {
    static dispatch_once_t once;
    static NSString *sharedString;
    dispatch_once(&once, ^{
        sharedString = [NSString
            stringWithContentsOfFile:@"MyFile"
            encoding:... // ...supply proper parameters here...
            error:...];
    });
    return sharedString;
}

这种设置静态对象的方法是线程安全的。即使从多个线程同时调用该方法,sharedString也会被初始化一次。

现在,您可以通过拨打[MyClass stringFromFile]从任意位置访问您的字符串。

答案 1 :(得分:1)

为要访问的类实例创建实例变量,并在指定的初始化器中创建静态变量。您指定的初始化程序应创建一次字符串对象(将其保留在静态变量中)并每次将其分配给实例变量。例如:

@implementation TestClass {
    NSString *_myString;
}

- (id)init {
    self = [super init];
    if (self == nil) return nil;

    static dispatch_once_t once;
    static NSString *aString = nil;
    dispatch_once(&once, ^{
        aString = ... // However you want to instantiate the string
    });
    _myString = aString;

    return self;
}

这使您可以访问实例方法中的字符串,就好像它是一个普通的实例变量一样,尽管字符串只创建一次并且每个实例都指向单个对象。

答案 2 :(得分:0)

- (NSString *)doSomething:(NSUInteger)aParam { 

    static NSString *foo = nil;

    if (!foo) {
        //load foo
    }

    return @"";  
}

答案 3 :(得分:0)

这将为您提供正确的指导。

Singleton Instance

A note on Objective-C singletons