10

如何在objective-c中制作静态初始化器(如果我的术语是正确的)。基本上我想做这样的事情:

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

但我想做这个更像结构,即不仅有一个 NSString 用于这个数组中的每个元素,而是一个 NSString 加上一个 NSArray,其中包含可变数量的 MyObjectType ,其中 MyObjectType 将包含一个 NSString、几个整数等.

4

4 回答 4

15

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

所以你不能这样做:

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

相反,您必须这样做:

static NSArray *myStaticArray = nil;

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

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

于 2011-02-16T05:52:24.890 回答
7

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

static NSArray *myStaticArray = nil;

- (void) someMethod {
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    myStaticArray = [[NSArray alloc] init...]
  });
}
于 2011-06-30T20:46:08.757 回答
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;
}
于 2011-02-16T06:46:52.807 回答
2

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

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

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

ps 你永远不应该调用 +initialize 自己。

于 2015-01-09T11:52:16.510 回答