2013年2月 のアーカイブ

Objectve-Cでクラスのインスタンスメソッドを書き換える

つい最近までiOS用のコードを書いていたのですが、その中でとあるオープンソースのライブラリを使用しています。でその中のとあるインスタンスメソッドの処理を書き換える必要がありました。
カテゴリ使って書き換えようと思ったのですが、その処理自身がカテゴリで定義されていたため無理でした。

まあライセンスに問題なければソースを直接修正すれば良いのですが、ライブラリのアップデートとかに備えておきたいとこです。
そこでclass_replaceMethodを使って書き換える方法に落ち着きました。

//ExampleClassのexampleMethodを書き換える例

#import 

...

id class = [ExampleClass class];//クラス定義取得
SEL sel = @selector(exampleMethod);//セレクタ取得

void (^block)() = ^{
  //処理を書き換える
};

IMP imp = imp_implementationWithBlock(block);//BlocksからIMPを生成

Method method = class_getInstanceMethod(class, sel);//元のインスタンスメソッドを取得
char* types = method_getDescription(method)->types;//インスタンスメソッドの引数の型を取得
class_replaceMethod(class, sel, imp, types); //書き換え!

これをAppDelegateなんかで実行しておけばOKです。

Facebooktwitterlinkedintumblrmail

Androidアプリのメモリリークを調査する

Androidでメモリリークを調査することがあったので手順を記述します。

1.Eclipseをダウンロードします。
    そこから!?と思うかもしれませんが一応書いておきます。

    http://www.eclipse.org/downloads/

    ここからEclipse Classic 4.2.1をダウンロードします。

    (※http://developer.android.com/sdk/index.htmlここから、
    EclipseとSDKが一括のものがダウンロード出来ますが
    プラグインが上手く入らなかったのでこれは使いませんでした。)

2.ADTをインストールします。
    1)Help→Install New Software
    2)addボタンを押して、以下のように設定します。
    3)適当に必要なものをインストールします。

3.BIRTプラグインをインストールします。
    1)Help→Install New Software
    2)Work withで「Juno – http://download.eclipse.org/releases/juno」を選択します。
    3)BIRTEnginをチェックします。
    4)インストールします。

4.Memory Analyzerプラグインをインストールします。
    1)Help→Install New Software
    2)Work withで「Juno – http://download.eclipse.org/releases/juno」を選択します。
    3)Memory Analyzerをチェックします。(Generale Purpose Toolsの中にあります。)
    4)インストールします。

5.DDMSのPerspectiveを開きます。
    1)対象のプロセスを選択して、「Dump HPROF file」を押します。
    2)表示されたダイアログで「Leak Suspects Report」をチェックし、「Finish」を押します。

メモリリークの詳細が表示されます。

Facebooktwitterlinkedintumblrmail

NSDictionaryのdictionaryWithObjectsAndKeysが辛い

iOS開発をやっていて、NSDictionaryでよく使うdictionaryWithObjectsAndKeys、NSArrayのarrayWithObjectsですが、下記のように入れ子になってくると何のこっちゃ分からなくなります。

NSDictionary *dictionary1 = [NSDictionary dictionaryWithObjectsAndKeys:
                             @"Taichiro", @"firstname",
                             @"Yoshida", @"lastname",
                             [NSArray arrayWithObjects:
                              [NSDictionary dictionaryWithObjectsAndKeys:
                               @"twitter", @"type",
                               @"dataich", @"id",
                               nil
                               ],
                              [NSDictionary dictionaryWithObjectsAndKeys:
                               @"facebook", @"type",
                               @"dataich", @"id",
                               nil
                               ],
                              nil],
                             @"accounts",
                             nil
                             ];

NSLogで出力した結果を見ると、下記のようなシンプルな内容なのですが。

{
    accounts =     (
                {
            id = dataich;
            type = twitter;
        },
                {
            id = dataich;
            type = facebook;
        }
    );
    firstname = Taichiro;
    lastname = Yoshida;
}

これをもう少し簡単にかける方法があります。
dictionaryWithObjectsAndKeysには @{}
arrayWithObjectsには @[]
というリテラル?が用意されてます。
これを使って書き直すと下記のようになります。

NSDictionary *dictionary2 = @{
                              @"firstname" : @"Taichiro",
                              @"lastname"  : @"Yoshida",
                              @"accounts"  : @[
                                                @{
                                                    @"type" : @"twitter",
                                                    @"id"   : @"dataich"
                                                },
                                                @{
                                                    @"type" : @"facebook",
                                                    @"id"   : @"dataich"
                                                }
                                             ]
                              };

ちょっとは見やすくなりますね!

Facebooktwitterlinkedintumblrmail