Tag Archives: Cocoa

スレッド毎にNSManagedObjectContextを管理する

基本的にはNSManagedObjectContextはスレッド毎に作成して利用しなければいけません。以下は、その為にスレッド毎にContextを作成して管理するためのコードです。複雑なアプリでなければ、この管理法で十分でしょう。シングルトンなManagerクラスでコンテキストを管理する方法は簡単ですが、スレッドを多用する場合はスレッド毎に管理する方が良いでしょう。

managedObjectContextForCurrentThreadでコンテキストを取得し、保存は[NSManagedObjectContext save:&error]のように、クラスメソッドを呼びます。保存するとNSNotificationでコンテキスト自身のmanagedObjectContextDidSave:が実行され、メインスレッドのコンテキストに変更が反映されます。スレッド毎に自動的にthreadDictionaryにNSManagedObjectContextを登録し、スレッドが破棄されるとコンテキストも破棄されるようになっているので、明示的にコンテキストを破棄する必要はありません。

@interface NSManagedObjectContext (Extras)
+ (NSManagedObjectContext *)managedObjectContextForThread:(NSThread *)thread;
+ (NSManagedObjectContext *)managedObjectContextForCurrentThread;
+ (NSManagedObjectContext *)managedObjectContextForMainThread;
+ (BOOL)save:(NSError **)error;
@end
#import "NSManagedObjectContextExtras.h"
 
NSString * const NSManagedObjectContextThreadKey = @"NSManagedObjectContextThreadKey";
 
@interface NSManagedObjectContext ()
- (void)managedObjectContextDidSave:(NSNotification*)notification;
@end
 
@implementation NSManagedObjectContext (Extras)
 
+ (NSManagedObjectContext *)managedObjectContextForThread:(NSThread *)thread {
    NSMutableDictionary *threadDictionary = [thread threadDictionary];
    NSManagedObjectContext *context = [threadDictionary objectForKey:NSManagedObjectContextThreadKey];
 
    if (!context) {
#ifdef TARGET_OS_IPHONE
        id appDelegate = [[UIApplication sharedApplication] delegate];
#else
        id appDelegate = [NSApp delegate];
#endif
        NSManagedObjectContext *mainContext = [appDelegate managedObjectContext];
 
        if ([[NSThread currentThread] isMainThread]) {
            context = mainContext;
        } else {
            context = [[[NSManagedObjectContext alloc] init] autorelease];
            [context setPersistentStoreCoordinator:[mainContext persistentStoreCoordinator]];
        }
 
        [threadDictionary setObject:context forKey:NSManagedObjectContextThreadKey];
    }
 
    return context;
}
 
+ (NSManagedObjectContext *)managedObjectContextForCurrentThread {
    return [NSManagedObjectContext managedObjectContextForThread:[NSThread currentThread]];
}
 
+ (NSManagedObjectContext *)managedObjectContextForMainThread {
    return [NSManagedObjectContext managedObjectContextForThread:[NSThread mainThread]];
}
 
+ (BOOL)save:(NSError **)error {
    NSManagedObjectContext *context = [NSManagedObjectContext managedObjectContextForCurrentThread];
    BOOL isMainThread = [[NSThread currentThread] isMainThread];
 
    if (!isMainThread) {
        [[NSNotificationCenter defaultCenter] addObserver:context
                                                 selector:@selector(managedObjectContextDidSave:)
                                                     name:NSManagedObjectContextDidSaveNotification
                                                   object:context];
    }
 
    BOOL result = [context save:error];
 
    if (!isMainThread) {
        [[NSNotificationCenter defaultCenter] removeObserver:context
                                                        name:NSManagedObjectContextDidSaveNotification 
                                                      object:context];
    }
 
    return result;
}
 
- (void)managedObjectContextDidSave:(NSNotification*)notification {
    NSManagedObjectContext *context = [NSManagedObjectContext managedObjectContextForMainThread];
 
    [context performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                              withObject:notification
                           waitUntilDone:YES];
}
@end
Log

NSStringとNSNumberにRubyのtimesみたいなのを生やしてみた

実用性は不明…

使い方は単純に
[@"5" times:^{ [foo bar]; }];
[[NSNumber numberWithInt:5] times:^{ [foo bar]; }];
みたいに。

Log

Objective-C/Cocoaにおける例外の利用についてのメモ

Objective-C/Cocoaでの例外の利用についてのメモ。

例外は以下のような予期されない論理上のエラーを伝播するために利用する。

  • 配列の添字が境界外である
  • 不変オブジェクトに変更を試みた
  • 引数の型が不正

このような例外はテストで捕捉して問題を解決するもので、アプリケーション利用時には例外を処理する必要は無いというのがあるべき姿である。

予期されるエラーを捕捉するために例外の代わりにエラー(NSError)を利用する。

未分類

オープンソースの統合ソフトウェア開発環境『Eclipse』がCocoaをサポート!: Podcast journal – ポッドキャストジャーナル

iPhoneアプリケーションの作成に使用されているCocoa。今まではCocoaと言うと統合開発環境としてXcodeを使っていた人が多いと思うのですが、選択肢として新たに「Eclipse」が加わりました。オープンソースの統合ソフトウェア開発環境『Eclipse』がCocoaをサポート!: Podcast journal – ポッドキャストジャーナル

Xcodeの方がIBとの親和性も高いだろうし、速度も有利だと思いますが、Eclipseの拡張性や他の言語プロジェクトとの連携を考えると、Eclipseも良さそうな気がします。

もっともXcodeが正式にPlugin対応すれば嬉しいんですが。

で、Eclipse 3.5をインストールしてみましたが、UI、特にメニューとPreferenceがMac的になってるんで、嬉しかったです。速度はまだインストールしただけなんでわかんないですが。

Get Adobe Flash playerPlugin by wpburn.com wordpress themes