2011-02-16 19 views
10

如何在objective-c中创建静态初始化器(如果我有术语正确的话)。基本上,我想要做这样的事情:目标中的静态初始化器C

static NSString* gTexts[] = 
{ 
    @"A string.", 
    @"Another string.", 
} 

但我想这样做,更多的结构类似,即有不只是一个NSString这个阵列中的每个元素,而是一个NSString加上一个NSArray中包含可变数目的MyObjectType,其中MyObjectType将包含NSString,一对整数等。

回答

14

由于NSArraysMyObjectTypes是堆分配对象,因此不能在静态上下文中创建它们。您可以声明变量,然后在方法中初始化它们。

所以你不能做的:

static NSArray *myStaticArray = [[NSArray alloc] init....]; 

相反,你必须做到:

static NSArray *myStaticArray = nil; 

- (void) someMethod { 
    if (myStaticArray == nil) { 
    myStaticArray = [[NSArray alloc] init...]; 
    } 
} 

发生与常量字符串(@"foo"等)工作,因为他们没有按堆分配。它们被硬编码到二进制文件中。

+0

那么“someMethod”不能只是初始化方法吗? – 2011-02-16 06:01:37

+0

@肯定它可以:) – 2011-02-16 06:14:19

2

这里有一个方法,如果你可以用objc住++编译:

#import <Foundation/Foundation.h> 

namespace { // ok, this storage should preferably be in a function/deferred 
    static struct sa { NSString* const s; NSArray* const a; } r = { 
     [[NSString alloc] initWithString:@"hello"], 
     [[NSArray alloc] initWithObjects:@"w", @"o", @"r", @"l", @"d", @"= =", nil] 
    }; 
} 

int main(int argc, const char* argv[]) { 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
    NSLog(@"\n\n%@...\n\n...\n%@", r.s, r.a); 
    [pool drain]; 
    return 0; 
} 
7

这是非常重要的,你要确保你的静态初始化是线程安全的(提供的iOS 4.1 +)!

static NSArray *myStaticArray = nil; 

- (void) someMethod { 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    myStaticArray = [[NSArray alloc] init...] 
    }); 
} 
2

在使用任何类方法或实例创建之前,+ initialize方法会自动在第一次使用类时调用。

+ (void) initialize { 
    if (self == [MyClass class]) { 
    // Once-only initializion 
    } 
    // Initialization for this class and any subclasses 
} 

+初始化由子类继承,并且还为每个没有实现自己的初始化的子类调用。如果你天真地在+初始化中实现单例初始化,这可能会特别有问题。解决方案是检查类变量的类型。

p.s你不应该自己调用+初始化。