Log

MacBook Pro early 2011にCrucial m4 SSDを載せる

MacBook Pro earlyに2011を載せてみた。うわさ通りレインボーカーソルがまわってフリーズしたようになった。ので、ファームウェアをアップデートしてみることにした。

Macでのアップデートのやり方の情報がすくなかった。少ない情報から以下のようにやってみた。

Crucial.com Product Downloads – Firmware Updatesからm4用のファームウェアisoをダウンロードしてDVDを作成。MBP early 2011ではアップデートができないらしいので、以前使っていたMacBookにm4をとりつける。DVDから起動して、指示に従う(yesを入力するくらい)。アップデート終了したらm4をMBPにとりつける。

以上で完了。レインボーカーソルが表示されることがなくなり、とても快調になった。

Log

Mac (Lion) にzshをインストール

Lionにzshをインストールした。以前もやったのだが、記録がなかったのでとどめておく。

zshをHomebrewでインストールする。

$ brew install zsh

/ect/shellsに/usr/local/bin/zshを追加する。

システム環境設定の「ユーザとグループ」を開く。鍵を開く。
シェルを変更したいユーザを右クリックして詳細オプションを開く。
ログインシェルを/usr/local/bin/zshに変更する。

Log

Safari5.1でEvernoteクリッパープラグインが使えないのでブックマークを使用する

Safari5.1になってEvernoteクリッパープラグインが使えなくなっていますね。

しかたがないので、そのうち対応されることでしょうからそれまでの間はブックマークレットを使用してクリップすることにします。

追記: Safari 5.1からEvernoteにPDFで保存する方法について記事を書きました。

Log

MacでImageMagick+RMagickを使う

ImageMagickとRMagickを使うべくhomebrewとgemでインストールした。

$ brew install imagemagick
$ gem install rmagick

で、使ってみるとSegmentation faultがでる。検索した結果、以下のように再インストールすれば使えるようになった。

brew install -f imagemagick --disable-openmp

つぎにannotationを使おうとするとフォントが無いと言われる。ので
ftp://ftp.imagemagick.org/pub/ImageMagick/delegates/ghostscript-fonts-std-8.11.tar.gz
をダウンロードして、以下のように/usr/local/share/ghostscriptに展開する。

$ mkdir /usr/local/share/ghostscript
sudo tar xzf ghostscript-fonts-std-8.11.tar.gz -C /usr/local/share/ghostscript

これでやっと利用できるようになった。

Log

UserInterfaceState.xcuserstateがgitで邪魔なのでignoreする

Xcode4になってUserInterfaceState.xcuserstateファイルが作成されるようになった。これがくせ者でXcodeを触るとすぐに変更されてしまって、gitで管理しているとコミットかチェックアウトしないといけなくなってしまう。

ので.gitignoreに加えた。

で、加えるだけでは駄目で、

git rm --cached ProjectFolder.xcodeproj/project.xcworkspace/xcuserdata/myUserName.xcuserdatad/UserInterfaceState.xcuserstate
git commit -m "hoge"

とする必要がある。

Log

かなキーをコントロールキーにしてみた

KeyRemap4MacBookで「かな」キーをコントロールキーにしてみた。

これまでは小指でコントロールキーを押していたけど、親指でおせると少しは楽かもしれない。

親指シフトを使っていて英数キーは親指シフトキーなのでコントロールにはできない。コントロールにするには英数キーの方があっているかもしれない。かなキーだとCtrl-Mが押しにくい。それは我慢ということで。

UINavigationControllerのアニメーションをカスタマイズする方法

UINavigationControllerでビューコントローラーをpush/popするときのアニメーションはスライドです。このアニメーションをカスタマイズしてみます。

ここではフェードを行ってみます。

まずはpushです。

- (IBAction)push {
    SubViewController *subViewController = [[[SubViewController alloc] initWithNibName:nil bundle:nil] autorelease];
    subViewController.view.frame = self.view.bounds;
    subViewController.view.alpha = 0.0;
    [self.view addSubview:subViewController.view];
 
    [UIView transitionWithView:subViewController.view duration:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void) {
        subViewController.view.alpha = 1.0;
    } completion:^(BOOL finished) {
        [self.navigationController pushViewController:subViewController animated:NO];
    }];
}

pushする対象はSubViewControllerです。現在のビューと同じサイズに設定して、透明にして、現在のビューにaddSubviewします。
アニメーションですが、alphaを1.0にして不透明にします。アニメーションが完了したらpushViewController:animated:でpushを行います。animatedにはNOを指定して、デフォルトのスライドアニメーションを行わないようにします。

次にpopです。

- (IBAction)pop {
    NSArray *viewControllers = [self.navigationController viewControllers];
    NSUInteger previousIndex = [viewControllers count] - 2;
    UIViewController *previousViewController = [viewControllers objectAtIndex:previousIndex];
    previousViewController.view.alpha = 0.0;
    [self.view addSubview:previousViewController.view];
 
    [UIView transitionWithView:previousViewController.view duration:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void) {
        previousViewController.view.alpha = 1.0;
    } completion:^(BOOL finished) {
        [self.navigationController popViewControllerAnimated:NO];
    }];
}

viewControllers から、pop後に表示される前のビューコントローラーを取得します。viewControllers配列の後ろから2番目に入っています。このコントローラーのビューのalphaを0.0に設定して透明にして、現在のコントローラーのビューに載せます。
アニメーションも同様にalphaを1.0に設定して、不透明にします。アニメーションが終了したらpopViewControllerAnimated:でpopします。これもNOを指定してデフォルトアニメーションを行わないようにします。

このように、UINavigationControllerでのフェードアニメーションは、push/popはどちらも、これから表示するビューを上に載せて、透明から不透明にアニメーションを行い、アニメーションが終了したタイミングでpush/popを行うことになります。

スレッド毎に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

Tacticon 2.1を公開しました

Tacticon 2.1を公開しました。

変更点は

  • 関連付けなどを行って連絡先一覧ビューにもどるときに異常終了する問題の修正
  • mixiの認可を必要な時に表示するように変更

です。

iCloudは「クラウド」なのか

「クラウド」は正式(?)にはクラウドコンピューティングといい、どちらかというとネットワークとハードウェアのハンドリングについて意味する言葉です。ネットワーク・コンピューティングを言い換えただけで宣伝文句がかわっただけという指摘もあるくらいです。

iCloudもネットワークやハードウェアはたしかに「クラウド」になっています。が、それだけではないシステムのようです。データのハンドリングまで雲の中に隠れて行ってくれるようになっているようです。「クラウド」はネットワークやハードは雲の中に隠れていましたが、ユーザはデータの同期などまだまだ意識する点がありました。iCloudは目の前のデータすら雲に入れて、「体験する」クラウドを提供することになるのではないでしょうか。

つまりiCloudは、これまで言い換えただけといわれていたハード中心の「クラウド」から、体験としてのクラウドに「進化」したといえるのではないでしょうか。

(まぁ、使ってみないことには分からないですけどね。)

Get Adobe Flash playerPlugin by wpburn.com wordpress themes