統計情報(30日間)


最新情報をツイート


人気の投稿

スレッドでビューを更新しているバグを見つける

このエントリーをはてなブックマークに追加

Method Swizzlingを使い、-[UIView setNeedsDisplay] を置き換えてメインスレッド以外で呼び出されるケースを検出するという話。



(void)toggleViewMainQueueChecking
{
    [UIView swizzleMethod:@selector(setNeedsLayout) 
            withMethod:@selector(_setNeedsLayout_MainQueueCheck)];
    [UIView swizzleMethod:@selector(setNeedsDisplay) 
            withMethod:@selector(_setNeedsDisplay_MainQueueCheck)];
    [UIView swizzleMethod:@selector(setNeedsDisplayInRect:)
            withMethod:@selector(_setNeedsDisplayInRect_MainQueueCheck:)];
}

そしてこんな感じで仕掛けておく
- (void)methodCalledNotFromMainQueue:(NSString *)methodName
{
    NSLog(@"-[%@ %@] being called on background queue. Break on -[UIView methodCalledNotFromMainQueue:] to find out where", NSStringFromClass([self class]), methodName);
}
 
- (void)_setNeedsLayout_MainQueueCheck
{
    if (dispatch_get_current_queue() != dispatch_get_main_queue())
    {
        [self methodCalledNotFromMainQueue:NSStringFromSelector(_cmd)];
    }
 
    // not really an endless loop, this calls the original
    [self _setNeedsLayout_MainQueueCheck]; 
}

シンボルブレークポイントを仕掛けておくと便利。



仕組みは単純だがいいアイディア。


Xcode デバッグマスター

このエントリーをはてなブックマークに追加

主にブレークポイントの活用方法など。参考になった。



いくつか紹介してみる。


%B でメソッド名表示。またコンソールへ表示するかわりに音声で読み上げることもできる。viewDidLoadにしかけたらちゃんと「びゅー・でぃど・ろーど」と読み上げてくれた。意外に役立つかも。


こちらは効果音。カスタム音の置き場所の解説もある。あらかじめ音の役割を決めておくと問題発見に役立つかもしれない。


expr を使うと文を記述することができる。単純な poコマンドに比べ書式付きで表現できる。これを使えばソースコードにNSLogを書く必要が無くなるかも。なお戻り値を明示(例ではvoid)してあげる必要があるようだ。


条件も同様に普通の文が記述できる。戻り値は明示的に(BOOL)キャストしておく。

他に #コメントの書き方や、DBファイル削除シェルスクリプトをブレークポイントで実行する方法など参考になった。


ps.なんか洋画の邦題っぽいタイトルになってきた。




デバッグ中の変数書き換え

このエントリーをはてなブックマークに追加



lldbだと expr で実行途中で値を書き換えることができる。


LLDBコマンドリファレンス




空ループをワーニングで見つける

このエントリーをはてなブックマークに追加

Xcode 4.6 から追加された Empty Loop Bodies を使うと空のループを検出することができる。





空のループとは if (x==0); や while(i); みたいなやつ。

こんな感じで検出できる。



自分の場合 {}を必ず書くのであまりこのケースは遭遇したことがほとんど無いと思うが、破壊力あるバグなので有効にしておいて損はないかも。


Xcodeデバッグ Tips

このエントリーをはてなブックマークに追加

デバッグ Tipsのいいまとめ。Cmd+\ でブレークポイントが設定できるのか。



Edit Schmeでアプリデータの指定もできるらしい。
Edit Schmeを改めて見てみると、シミュレータデバイスの種類など色々設定できるのか。


F-Scriptライクな iOSリモートデバッガ superdb

このエントリーをはてなブックマークに追加

スーパーなデータベースではなくデバッガ。OS X アプリから iOS アプリをリモートデバッグできるツール&ライブラリ。



iOSアプリへ組み込むライブラリと、OS X アプリの2つから構成される。組み込んだライブラリはアプリ実行時にポートを開き、OS X アプリからの通信を受け入れるようになる。OS X アプリはデバッグコンソールを提供する。

こんな感じでコンソールからリアルタイムに iOSアプリの実行時情報を見たり変更を加えたりすることができる。これはいい。

デバッグコンソールは F-Scriptシンタックスな文法を使う。

- - - -
試したところビルドできたものの OS Xのコンソールがうまく動かなかった(残念)。

組み込み型プロファイラ

このエントリーをはてなブックマークに追加



メソッドの呼び出し回数や実行時間の統計を取ることができる。

グラフ化もサポート

丁寧なインストールマニュアルあり。
hookshot/Documentation/INSTALL.md at master · Cue/hookshot · GitHub


ツールはライブラリ(Objective-C++)とPythonスクリプトから構成される。統計を取るにはあらかじめライブラリを自分のプロジェクトへ組み込み、計測対象にしたいクラスをソースコードで指定しておく必要がある。
HOOKSHOT_PROFILE_CLASS([AppDelegate class]);
HOOKSHOT_PROFILE_CLASS([UIWebView class]);
HOOKSHOT_PROFILE_CLASS_EXCEPT([AnotherClass class],
    [NSValue valueWithPointer:@selector(someFrequentlyCalledSelector)],
    [NSValue valueWithPointer:@selector(anotherFrequentlyCalledSelector)])

アプリの実行中にこのライブラリが計測情報を ~Documentsフォルダへ書きだす。profile.py を実行してそれを統計出力する仕組みのようだ。

いろいろな条件でフィルタすることも可能。

・スレッド指定
$ bin/profile.py --thread WebThread

・正規表現
$ bin/profile.py --message '.*did'

・クラス
$ bin/profile.py --class 'AppDelegate'


他にインスタンス数の統計など
HOOKSHOT_COUNT_INSTANCES(cls);
↓結果
HookshotDemo[25220:11303] UIImage: 8 (after dealloc)


なお、このライブラリは非公開APIを使っている。作成者はリリースに支障が無いセットアップ方法を提示しているので利用の際は参照のこと。


クラッシュログの解析

このエントリーをはてなブックマークに追加





クラッシュログの基本的な読み方の他、ケーススタディの解説もあって詳しい。

Exception Codes の紹介もある。

0x8badf00d: Reads as “ate bad food”! ..

0xbad22222: This code indicates that a VoIP application was terminated by iOS because it resumed too frequently.

0xdead10cc: Read this one as “dead lock”!...

0xdeadfa11: Another cute code – read it as “dead fall”!...

デバッグに便利なNSObjectカテゴリ- DLIntrospection

このエントリーをはてなブックマークに追加



定義はこんな感じ。
@interface NSObject (DLIntrospection)

+ (NSArray *)classes;
+ (NSArray *)properties;
+ (NSArray *)instanceVariables;
+ (NSArray *)classMethods;
+ (NSArray *)instanceMethods;

+ (NSArray *)protocols;
+ (NSDictionary *)descriptionForProtocol:(Protocol *)proto;


+ (NSString *)parentClassHierarchy;
@end



プログラムで使うというよりもデバッグで使う。


発想は悪くない。objc/runtime.hの使い方の参考にもなる。

クラッシュログ解析サービスの比較

このエントリーをはてなブックマークに追加

crittercism と bugsense の比較。参考になった。







有料プラン、無料プランでそれぞれの特徴をまとめてくれている。
crittercism, bugsense ともに無料プランがあります。無料プランに限って言えば crittercism の圧勝という感じです。

bugsense の無料プランにはシンボルの復元機能がありません。crittercism は iOS の dSYM復元および Android の proguard 復元の両方ができます。
bugsense の無料プランは1ヶ月あたり500件までしかログを取得できません。cirttercism は制限なし?
有料プランの比較
有料プランになると若干状況が変わります。一番安いプランに関していうと、crittercism は Premium プランで $24/月、bugsense は Indie プランで $19/月、なのであまり価格差はないように見えます。。。

crittercism は無料プランでもクラッシュログ取得に絞れば結構使えそうとのこと。

Crashlytics

このエントリーをはてなブックマークに追加



  • サーバーの設置&運用の必要がない
  • Crashlytics for MacでdSymの自動アップロード
  • ベータ版なので最終的なコストが分からない
  • 開発者向けサービスとは思えないレベルのUX

負荷に関しては自信があるらしく、米AppStoreで15位に入ったアプリをいくつかホストしているとのことでした。


Crashlytics のホームページ

ベータテスト中とのこと。

NSURLConnection の sendAsynchronousRequest を lldbで追う

このエントリーをはてなブックマークに追加

lldb を駆使して sendAsynchronousRequestの挙動を追っていく描写が臨場感があって面白い。lldbを使ったデバッグのいいお手本。とても参考になった。



記事内で紹介されていた LLDB と GDB の対比早見表。