2011-02-16 7 views
10

어떻게 목표 -c에서 정적 이니셜 라이저를 만들 수 있습니까? 기본적으로 나는이 같은 싶지 :객관적인 C의 정적 이니셜 라이저

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

을하지만이보다 구조체 같은 싶지 즉,이 배열의 각 요소에 대해 그냥있는 NSString을 가지고 있지만 대신있는 NSString 더하기 하나는있는 NSArray가 포함 된 MyObjectType에 NSString, 몇 개의 정수 등이 포함될 수있는 MyObjectType의 변수 번호

답변

14

NSArraysMyObjectTypes은 정적 할당 컨텍스트에서 만들 수 없기 때문에 사용할 수 없습니다. 변수를 선언하고 메소드에서 변수를 초기화 할 수 있습니다.

그래서 당신이 할 수 없습니다

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

를 대신 수행해야합니다

static NSArray *myStaticArray = nil; 

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

를 발생이 상수 문자열 (@"foo" 등)에 대한 작업, 그들은 힙에되지 않기 때문에 할당 된. 그것들은 바이너리에 하드 코딩되어있다. 당신이 objc 살 수 있다면

+0

그래서 "someMethod"는 초기화 방법 일 수 없습니까? –

+0

@Ken 할 수 있는지 확인하십시오 :) –

2

여기, 하나의 방법 ++ 번역 :

#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

그것은 매우 중요합니다 당신이 정적 초기화가 (아이폰 OS 4.1 +에서 사용 가능) 스레드 안전 있는지 확인하는 것이!

+0

NSObject라면 배열을 확실히 사용하려면'+ (void) initialize '에 넣지 않으시겠습니까? – qix

+0

이것은''someMethod''가 다중 스레드에서 호출 될 수있는 경우에만 필요합니다. 특히 스레드 안전성을 필요로하는 * 정적 초기화 자체에는 아무 것도 없습니다. – Ben

2

+ initialize 메서드는 클래스를 처음 사용할 때, 클래스 메서드를 사용하거나 인스턴스를 만들기 전에 자동으로 호출됩니다.

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

+ 초기화는 하위 클래스에 상속되며 + 자신의 + 초기화를 구현하지 않는 각 하위 클래스에 대해서도 호출됩니다. + 초기화에서 싱글 톤 초기화를 순진하게 구현하면 특히 문제가 될 수 있습니다. 해결 방법은 클래스 변수의 유형을 확인하는 것입니다.

p.s 자신을 + 초기화하지 마십시오.