2012年8月28日火曜日

XCode4で、メモリリークをデバッグ

検索してもなかなかゴールまでたどり着かなかったのでメモ。
なぜなかなか引っかからなかったかというと、XCodeのバージョン。
3はあるけど、4はない、みたいな。

取りあえず、以下の通り。

まず、「Manage Schemes...」を選択
開いているProjectを選択して、画面左下の「Edit」を押下。

画面の右ペインに「Environment Variables」という所があるので、
図のように3項目をvalue=YESで設定してあげる。
すると、DebugConsoleに誰がどこでalloc、freeしたががわかるようになる。
早速、EXC_BAD_ACCESSがでるコードをエミュレートしてみると、以下のようなログがでると思います。

2012-08-28 19:36:35.367 HelloWorld[38022:1be03] cocos2d: cocos2d v2.0.0
2012-08-28 19:36:35.368 HelloWorld[38022:1be03] cocos2d: Using Director Type:CCDirectorDisplayLink
2012-08-28 19:36:35.421 HelloWorld[38022:1be03] Retina Display Not supported
2012-08-28 19:36:35.428 HelloWorld[38022:1be03] cocos2d: animation started with frame interval: 60.00
2012-08-28 19:36:35.434 HelloWorld[38022:1be03] cocos2d: surface size: 480x320
2012-08-28 19:36:35.436 HelloWorld[38022:1be03] cocos2d: CCTexture2D: Using RGB565 texture since image has no alpha
[Switching to process 38022 thread 0x1f113]
[Switching to process 38022 thread 0x1be03]
2012-08-28 19:36:37.279 HelloWorld[38022:1be03] *** -[CCSprite zOrder]: message sent to deallocated instance 0xaa87e20
sharedlibrary apply-load-rules all
(gdb) shell malloc_history 38022 0xaa87e20

最後の行に「(gdb)」ってでると思うので、ここで「shell malloc_history {PID} {インスタンスアドレス}」というコマンドを打ってあげると、以下のようなログがでて、メモリの履歴を見れます。

ALLOC 0xaa87e10-0xaa87e4f [size=64]: thread_b024f000 |thread_start | _pthread_start | cvmDoWork | (省略) | malloc | malloc_zone_malloc 
FREE  0xaa87e10-0xaa87e4f [size=64]: thread_b024f000 |thread_start | _pthread_start | cvmDoWork | (省略) | free 
(省略)と書いた所に、自分が作成したクラス名とかメソッド名が記載されていたら、そこに問題アリって感じでデバッグできるよ。

コードをブログにキレイにカキタイ

以下を参考にしました。
特に難しいことは無いですが、黒背景のブログはめんどいね。

http://fascinating-pieces.blogspot.jp/2012/02/google-code-prettify-blogger.html

Objective-Cを独習

夏休みに予定を入れ忘れたので、Objective-Cを学ぼうと思います。

取りあえず、以下を読んである程度の文法を理解した。
http://wisdom.sakura.ne.jp/programming/objc/index.html

#検索したら、以下にキレイに文法がまとまっているサイトがありました。
http://d.hatena.ne.jp/fn7/20100203/1265207098

これを読んでわからなかった事について検索。

プロパティがよくわからん。
➡ 外部に公開しているインスタンス変数のこと。@propertyで宣言する。
以下の用に、ヘッダファイル内でインスタンス変数を宣言する方法は古いらしい。
➡ http://www.awaresoft.jp/ios-dev/item/115-ivar-naming-convention.html

@interface Hoge {
  NSString* a;
  NSInteger b;
}
@end

@synthesizeってなに?
➡ Getter、Setterをコンパイル時に自動生成して提供する。
でも、上記アクセサメソッド渡したら、インスタンス変数隠蔽できなくない?
➡ http://ishwt.net/blog/2010/05/21/objc20-property/
つまり、

@interface Hoge {
  NSString* a;
  NSInteger b;
@property (readonly, retain) NSString* a;
@property (readonly, assign) NSInteger b;
@end

って感じで、readonlyをつけると、外部からのアクセスにより書き換えられる心配はなくなりますってこと。

これからObjective-Cを学ぶなら、以下の本が良さそうなので購入してみた。




ちなみに、目標はcocos2dを使ってゲームを作ってみること。
以下の本が良書として推薦しているサイトが沢山あったが、既に新バージョンがでているため、購入はオススメしない。次作がでるまで待つか、他の本をあたろう。
#そりゃcocos2dのofficialが一番いいと思うけど。。。




現時点では、以下の本に期待。
#洋書なので、翻訳版が早くでることを期待して。

2012年8月6日月曜日

Java並行処理プログラミング1

【単一不可分(アトミック)】
 単一の操作で不可分なので、その操作は分けられません。
以下は、アトミックでは無い操作。
①read-modify-write
②check-then-act
①は、index++みたいなやつ。

この操作は、実際には以下の3つの操作をしています。

1、indexの値を取得
2、値を書き換え(1加算)
3、indexに書き込みます。

このように、複数回の操作をすることは、単一不可分では無いと言います。
じゃあ、どうするの?というと、単純に言えば同期すれば、この1、2、3が 1回の操作として実行されます。
これを単一不可分な操作という。つまり、アトミックです。

【逸出】 公開すべきでは無いオブジェクトが公開される事。

【不可変】 オブジェクトが不可変であるとは、、、
→コンストラクション後、ステートの変更ができない
→すべてのフィールドがfinalで、コンストラクション時にthis参照が逸出しない
という事です。
余談(?)ですが、コンパイラが最適化をすると、同期しないと実行順序が意図しない順序に変わる可能性があります。