Shuhei Kagawa

Xcode で例外発生時のスタックトレースをデバッガに表示

Nov 14, 2009

iPhone アプリの開発で例外が発生したとき、Xcode のコンソールにはスタックトレースのアドレス(?)が表示されるだけで、内容がわかりません。 Objective-C ランタイムの例外送出部分にブレークポイントを設定することで、例外発生時のスタックトレースやコード中のオブジェクトの値をデバッガで詳しく見ることができます。

方法

“実行” => “ブレークポイントを管理” => “シンボリックブレークポイントを追加” を実行します。

出てきたダイアログに objc_exception_throw と入力。 これで、例外が発生した時にブレークされ、デバッガで詳細を見る事ができるようになります。

デバッガなので、もちろんコード中のオブジェクトの値を見ることもできます。便利ですね。

via Debugging Tip – objc_exception_throw breakpoint | markjnet

シンボリックブレークポイント

通常のブレークポイントではソースコード中の行を指定しますが、シンボリックブレークポイントはシンボル単位で指定するブレークポイントです。 ですので「あの関数が呼ばれたらブレーク」や「あのクラスのあのメソッドが呼ばれたらブレーク」ということができます。 今回の objc_exception_throw は Objective-C のランタイム中にある例外を送出する関数のようですね。

ImageMagick で画像を一括リサイズ

Nov 7, 2009

特定の名前の画像をリサイズします。

#! /bin/bash

for f in rect_*.png;
do
  convert -resize 12x12! $f $f
done

コマンドラインは便利ですねー。 ひまを見てちょこちょこシェルスクリプトを勉強していきたいです。

Navigation-based Application に TabBar を追加

Nov 7, 2009

iPhone プロジェクトの新規作成時に “Navigation-based Application” を選んだ場合に、後から TabBar を追加する方法です。 InterfaceBuilder での設定が画像入りの説明なしではよくわからず、苦戦したのでメモしておきます。

InterfaceBuilder の設定

Tab Bar Controller の追加

まず、InterfaceBuilder で MainWindow.xib を開きます。 Navigation Controller を削除して Tab Bar Controller を追加します。

Tab Bar Controller の下に Navigation Controller を

Tab Bar Controller にフォーカスをあて、Inspector の一番左のタブ の “Tab Bar Controller” => “View Controllers” の中で Navigation Controller にするタブの Class を Navigation Controller に変更します。

すると、IB のメインウィンドウの方の Tab Bar Controller の子供の Controller の Type が UIViewController から UINavigationController に変わっているはずです。

Navigation Controller の下に Root View Controller を

この Navigation Controller のさらに子供の View Controller が、もともとの Root View Controller になるよう設定します。 一番左側のタブで NIB Name を、Inspector で一番右側のタブで Class を設定します。

以上を保存して IB を閉じます。

コードの修正

Xcode に戻って AppDelegate を変更し、UINavigationController ではなく UITabBarController を読み込むようにします。 以下、アプリケーションの名前を Hoge だったとして、 HogeAppDelegate.h と .m を編集します。

HogeDelegate.h

@interface HogeAppDelegate : NSObject  {
  UIWindow *window;
  UITabBarController *tabBarController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;

@end

HogeAppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application {
  [window addSubview:[tabBarController view]];
  [window makeKeyAndVisible];
}

synsthesizedealloc 中の release も忘れずに変更します。

App Delegate の Outlet のつなぎ変え

これまで App Delegate で UINavigationController を参照していたのを UITabBarController に変えたので、Outlet の設定が切れています。 再度 Interface Builder に戻って App Delegate の Outlet をつなぎ直します。

これで、Tab Bar Controller の下に Navigation Controller と View Controller、Navigation Controller の下に Root View Controller という構成になっているはずです。