トップ «前の日記(2011-05-14) 最新 次の日記(2012-01-01)» 編集

じじぃの日記、ツッコミ可

Twitter: @jijixi_org
Xbox Live: jijixi

初心者が書いた OCaml 入門
Spotlight tips サイト内リンク集
1970|01|02|
2003|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|11|
2011|05|
2012|01|

2011-05-26 [長年日記]

% [objc] こっそり忍び寄る未初期化変数の罠

以前 iOS アプリの開発でこんなことを書いてハマったことがある。

return self.someView.frame.size.height;

someView プロパティ (UIView のサブクラスの何か) には何も入っていない場合があるんだが、その場合、最初は 0 を返すもののしばらくすると変な値を返し始める。 デバッグ環境だとなかなかその現象が出ないので原因の特定に難儀したんだが、わかってしまえば「ああそうか、なんで気づかなかったんだ」という話。

Objective-C では nil に対するメッセージ (メソッド呼び出し) は何も起こらず nil が返ることになっているので、特にエラーを出す必要が無い場合にはつい nil かどうかのチェックを省略してしまうんだが、上記のような場合にはそれが仇になる。

UIView の frame プロパティの型は CGRect で、これはオブジェクトではなく構造体である。 構造体に関しては C そのものと考えていい。 つまり上記のようなコードは実際には以下のような処理の流れになっている (と思われる)。

UIView *aView = [self someView];
CGRect frame = [aView frame];
return frame.size.height;

aView が nil の場合、frame には nil が代入されるのだろう。 そうだとすれば当然それは CGRect の初期化としては不十分で、その結果、ある程度メモリ領域が汚れてくるとゴミ値が入ってくるので return される値がおかしくなる。 C の経験がある程度あれば当たり前の挙動ではあるが、そうでない場合にはさっぱり意味がわからないかもしれない。 やっぱり Objective-C を使う人は C も必修にした方がいいんじゃないか。

お名前:
E-mail:
コメント:

トップ «前の日記(2011-05-14) 最新 次の日記(2012-01-01)» 編集

日記ってのは本来、自分で読み返すためにあるもんだよなあ……
もしくは有名人になったら死後に本になったりとかか?

RSS はこちら

jijixi at azito.com