目标C中的静态初始化程序

时间:2011-02-16 05:47:18

标签: objective-c static initializer

如何在objective-c中创建静态初始值设定项(如果我的术语正确)。基本上我想做这样的事情:

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

但是我想这样做更像struct-like,即不仅仅是这个数组中每个元素的NSString,而是一个NSString加一个NSArray,它包含一个MyObjectType的变量,其中MyObjectType将包含一个NSString,一对英特尔等。

4 个答案:

答案 0 :(得分:15)

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

所以你做不到:

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

相反,你必须这样做:

static NSArray *myStaticArray = nil;

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

发生以使用常量字符串(@"foo"等),因为它们不是堆分配的。它们被硬编码到二进制文件中。

答案 1 :(得分:7)

确保静态初始化是线程安全的(在iOS 4.1 +中可用)非常重要!!!

static NSArray *myStaticArray = nil;

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

答案 2 :(得分: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;
}

答案 3 :(得分:2)

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

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

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

p.s你不应该自己打电话+初始化。