2009-03-08 3 views
4

I IB가없는 응용 프로그램을 작성할 계획이 아니므로 프로그래밍에 대해 자세히 배우려하고 있습니다.인터페이스 빌더가없는 코코아, 앱 컨트롤러의 인스턴스를 초기화 하시겠습니까?

시작시 AppController 클래스의 인스턴스 하나를 어떻게 얻을 수 있습니까? (이것은 일반적으로 펜촉에서로드됩니다.) 그리고 +initialize-init의 사용을 해결할 수 있습니까? 이해한다면 시작시 모든 클래스에 +initialize이 호출됩니다. 내 인터페이스를 구성하는 인스턴스 변수를 사용하여 AppController 인스턴스를 만드는 데 어떻게 이것을 사용할 수 있습니까?

호프는 의미가 있습니다. 도움을 주셔서 감사합니다.

답변

7

+initalize 처음으로 또는 클래스의 하위 클래스 중 하나가 처음으로 메시지를 수신하면 클래스로 전송됩니다. 그래서, 당신은 수행 할 때 alloc 메시지가 initialize를 트리거

instance = [[[YourClass alloc] init] autorelease]; 

있다. 서브 클래스와 같은 일을 할 경우

는 : alloc 메시지가 +[YourClass initialize] 다른 하나는했던 것과 같은 방식으로 트리거

instance = [[[SubclassOfYourClass alloc] init] autorelease]; 

그건 (사전도 +[SubclassOfYourClass initialize]을 유발하는 있지만 이들 중 하나는 - 그것을 할 것입니다. 각 클래스의 initialize 번 이상 호출되지 없구요. (당신이 [super initialize] 또는 [SomeClass initialize] 자신을 호출하지 않는 한 방법이 그것을 기대되지 않기 때문에 - 그래서는 그렇게하지 않습니다.)

-init, 다른 한편으로는, 초기화하다 새로운 인스턴스. 표현식 [[YourClass alloc] init]에서 직접 인스턴스에 직접 메시지를 보냅니다. 다른 이니셜 라이저 ([[YourClass alloc] initWithSomethingElse:bar]) 또는 편의 팩토리 ([YourClass instance])를 통해 간접적으로 호출 할 수도 있습니다.

initialize과 달리 항상 init (또는 적절한 경우 다른 초기화 도구)을 수퍼 클래스에 보내야합니다. (Wil Shipley doesn't assign to self at all를이 방법 또는 슈퍼 클래스의 또는 두 인수를 취할 수 있으며, 어떤 사람들은 한 줄에 self = [super init]을 선호하고)

- (id) init { 
    if ((self = [super init])) { 
     framistan = [[Framistan alloc] init]; 
    } 
    return self; 
} 

세부 사항은 다르지만, 기본적인 아이디어는 동일합니다 : 대부분의 초기화 방법은 다음과 같이 대략 볼 : [super init[WithSomething:…]]을 호출하고 nil을 반환하지 않았는지 확인하고 인스턴스가 설정되지 않은 경우 인스턴스를 설정 한 다음 수퍼 클래스가 반환 한 값을 반환합니다.

즉, nilinit에서 반환 할 수 있습니다. 이렇게하면 실패한 개체가 누출되지 않도록 [self release]을 실행해야합니다. (유효하지 않은 인수 값을 검출하기위한 대안은 어설 션이 실패 할 경우. 각각의 상대적인 장점이 질문의 범위를 벗어난 예외가 발생 NSParameterAssert입니다.)

내가 인스턴스를 만들려면이 사용 방법 내 인터페이스를 구성하는 인스턴스 변수가있는 AppController?

가장 좋은 방법은 main에 모든 것을 할 것입니다 :

int main(int argc, char **argv) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    AppController *controller = [[[AppController alloc] init] autorelease]; 
    [[NSApplication sharedApplication] setDelegate:controller]; //Assuming you want it as your app delegate, which is likely 
    int status = NSApplicationMain(argc, argv); 

    [pool drain]; 
    return status; 
} 

당신은 AppController에서 응용 프로그램의 대리자 메서드의 다른 셋업을 할 수 있습니다.

당신은 이미 이것을 알고 있습니다 만, 이것을 읽는 다른 사람에게는 : 님은 친구입니다. Interface Builder는 당신의 친구입니다. 프레임 워크와 싸우지 마십시오. 그래픽 작업을 통해 인터페이스를 구축하십시오. 그러면 응용 프로그램이보다 효과적으로 작동합니다.

+1

덕분에 도움이되었지만 IB가 꽤 많이하는 것처럼 보입니다. AppController에서 load interface라는 메서드를 만들고 main에서 호출했습니다. AppController * controller = [...] [컨트롤러 loadInterface]; 나는 (주석 계속) 내 컨트롤러 변수 MainWindow를에 값을 할당 할 때 ... – cemulate

+0

나는 콘솔 오류를 얻을 : _NXCreateWindow : 오류 설정 창 속성 (1002) _NSSetWindowTag, 오류 삭제 창 태그 (1002) _NSSetWindowTag를 , 오류 설정 창 태그 (1002) 이 문제를 해결할 수 있습니까? – cemulate

+0

윈도우를 만들기 전에 NSApplication을 실행시켜야합니다. 그렇기 때문에 컨트롤러를 응용 프로그램 위임자로 만들고 위임 메서드로 창을 만들거나로드하는 것이 좋습니다. (명령 행 응용 프로그램 *은 아직 NSApplication을 실행하지 않았기 때문에 창을 작성할 수 없습니다.) –

1

표준 Subversion 또는 SCM 스타일 도구와 비교하거나 병합하는 쉬운 방법이 없으므로 NIB 집합이 XML (XIB)로 표현되는 경우에도 만족스럽지 않은 대답 인 것 같습니다. 인코딩 된 정보는 허약하며 단순한 인간이 편집하지 못하도록되어 있습니다. 변경 사항은 GUI에 의해 어떻게 표현 될까요? 각 컨트롤의 각 속성을 단계별로 확인하고 시각적으로 확인합니까?

그러나 앱의 동작이 코드로 작성된 경우 많은 세부 사항을 동시에 처리해야하는 경우에도 진행 상황을 파악할 수있는 가능성이 있습니다.

해결책 : 기본 설계자가 코딩 한 최상위 NIB를 사용하고 나머지 앱을 명시 적으로 코딩합니다.

아무도 더 좋은 아이디어가 있습니까?

1

펜촉을 사용하지 않고 앱을 실행하는 문제에 대한 또 다른 해결책입니다. 대신 자신의 컨트롤러를 allocing의

, 단지 NSApplicationMain() 방법에 추가 매개 변수를 사용

int retVal = NSApplicationMain(argc, argv, @"UIApplication", @"MyAppDelegate"); 

이를 돌봐 모든 사람이 필요 연결 적당한.

다음으로 기억해야 할 유일한 점은 나만의 창을 만들고 시각적으로 설정하는 것입니다.

+0

greggT에 응답하십시오. 위에서 말한대로해라. 프로젝트의 시작 부분에서 모든 XIB 파일을 삭제하고 main.m으로 이동 한 다음 위에서 설명한 두 개의 매개 변수를 NSApplicationMain() 인수에 추가합니다. 그런 다음 appdelegate로 이동하여 자신의 창을 생성하고 (XIB를 사용하지 않으므로) 비 XIB ViewController 또는 NavController의 뷰를 해당 창에 추가합니다. keyandvisible로 만들고 XIB없이 전체 프로젝트를 생성했습니다. 이는 초기에 제공된 XIB가 의도 한대로 작동합니다. –

+0

정보를 수정하십시오.plist 프로젝트 설정에서 .xib 파일 이름을 삭제합니다. –

관련 문제