アーカイブ

2009 年 12 月 のアーカイブ

applicationWillTerminate: のメモ

2009 年 12 月 15 日 コメントはありません

NSApplicationDelegate Protocol の applicationWillTerminate: についてメモ。

applicationWillTerminate: は、アプリケーションが終了する直前に呼ばれる。ドキュメントによる最後のクリーンアップ処理を行うことを想定している。

applicationWillTerminate: は、applicationShouldTerminate: が NSTerminateNow を返したときに通知される。

そして、ウィンドウがひとつしかない場合や最後のウィンドウが閉じた場合には applicationShouldTerminateAfterLastWindowClosed: が呼ばれ、YESを返した場合には上記の applicationShouldTerminate: が呼ばれる。

まとめてみる。

- (BOOL) applicationShouldTerminateAfterLastWindowClosed: (NSApplication *)theApplication {
    // 最後のウィンドウが閉じられた
    // 問題があればNOを返す。問題がなければYESを返す。
    return YES;    // applicationShouldTerminate: が呼ばれる
}

- (NSApplicationTerminateReply)applicationShouldTerminate: (NSApplication *)sender
{
    // NSAppが終了しようとしている。
    // 問題があれば NSTerminateCancel を返す。
    // 問題がなければ NSTerminateNow を返す。
    return NSTerminateNow;    // applicationWillTerminate: が呼ばれる
}

- (void) applicationWillTerminate: (NSNotification *)aNotification
{
    // 最後のクリーンアップ処理を行う。
}

NSApplication の terminate: は、メニューの [アプリケーションを終了 ⌘Q] を実行すると勝手に呼ばれる。
ちなみに、terminate: は applicationShouldTerminate: を実行する。

普通にアプリケーションを終了する場合には、terminate: は実行しなくていい。

そんな感じ。

カテゴリー: Cocoa, Mac, Objective-C タグ:

NSThread detachNewThreadSelector:toTarget:withObject:

2009 年 12 月 5 日 コメントはありません

NSThread の detacheNewThreadSelector:toTarget:withObject: についてメモ。

例えば次のような意味の無いコードを実行すると、NSAutoreleaseNoPool のエラーが発生する。

- (void) hogeThread {
    NSMutableArray *anArray = [NSMutableArray array];
    int i = 0;
    while (isInThread) {
        [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
        [anArray addObject: [NSString stringWithFormat:@"%d". i++]];
    }
    [NSThread exit];
}

- (void) stopThread {
    isInThread = NO;
} 

- (void) doThread {
    isInThread = YES;
    [NSThread detachNewThreadSelector:@selector(hogeThread) 
                             toTarget:self 
                           withObject:nil];
} 

まず、NSMutableArray はクラスメソッド array によって autorelease 済みの状態で用意される。

また、NSStringも同様にクラスメソッド stringWithFormat: によって autorelease 済みで用意される。

通常、アプリケーションはメインスレッド用にAutoreleasePoolをひとつ持っている。

新しいスレッドを用意した場合、別途AutoreleasePoolを用意してやらないと、NSMutableArray とNSString でメモリリークが発生する。

- (void) hogeThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSMutableArray *anArray = [NSMutableArray array];
    int i = 0;
    while (isInThread) {
        [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
        [anArray addObject: [NSString stringWithFormat:@"%d". i++]];
    }
    [NSThread exit];

    [pool release];
}

これでOK。

カテゴリー: Cocoa, Mac, Objective-C タグ: