«前の日記(2009-09-01) 最新 次の日記(2009-09-05)» 編集

ぱぱネット(仮)


2009-09-02 まあ全体的には役立つ本なんだけどね [長年日記]

_ [iPhone][読書] iPhoneアプリケーションプログラミング

網羅的に様々な分野に触れていて良い本だと思ったんだがな..... 読んでみるとかなり酷かったので紹介します。

iPhoneアプリケーションプログラミング
新居 雅行
技術評論社
¥ 3,360

もうタイピングしてるだけでウンザリするわけだが、 どの程度酷いか理解してもらうために少し引用してみる。

p43

「まず、この@propertyによる宣言は必須となりますが、インスタンス 変数を{aka '定義'}}するかしないか、メソッドを自分で書くのかどうか、 @synthesizeを書くのかどうかという点については、 状況によって変わります。

しかし どのような状況で変わるのかまったく説明がない。 あるとすれば以下の項目だろうか。

p44

「プロパティageについてまず見てみましょう。オプションが何もないので ゲッタやセッタは指定されておらず、読み書き可能で、代入時はそのまま 代入されます。この場合、@synthesizeディレクティブを実装部記述 することで、同名のインスタンス変数ageに対しての代入や参照を行う ゲッタやセッタを背後で自動的に作り上げてプロパティとして機能する ようにします。 つまり、@synthesizeは文字通りメソッドを合成するということで実装部に記述します。整数データの場合は、単なる代入で多くの場合は問題ないでしょう。

いやいや、それまっったく説明になってないでしょう。「状況によって変わります=単なる代入で多くの場合は問題ないでしょう」。なに言ってるのかわかってますか?

次はもっとひどい。

p44欄外

「サンプルプログラムではnonatomicが付けられたプロパティがよく 見られます。これを書かないようにする必要があるのは複数のスレッド から書き込みが行われるようなプロパティです。書き込みが同時に発生 しないような場合は nonatomicと書いておく方が 良いでしょう。

この「新居雅行」という筆者にとって、どうもプログラミング言語というものが 「ああ、星が綺麗だな」とか「溶岩が吹き出ている」といった 現象として見えている ようだ。でもApple][やVIC-1001の頃から30年くらいコンピュータを学んできた程度の青二才に 言わせてもらえれば、

言語は'仕様'であって現象じゃない

仕様とは、Aという入力があれば必ず(バグを除き)f(A)という出力が 得られるもの。言い換えれば 思想 とも言うべきものだ。 ま、単なる素人には、状況や場面に応じて「ああ、書式が違うんだな」という 把握の仕方はありかもしれんけどさ、 そうなってしまう理由 、つまり必然があるのが プログラミング言語なんですよ。それを伝えるのが プロ の物書きとしての 義務なんじゃないの?

全体的に「あれもあります〜」「これもあります〜」「こういう可能性があります〜」と いう文体から、 実は全く内部構造を理解しないで本を書いている というのが伺えるけどね。

p45

「続いて、familyNameとgivenNameの場合を見てみます。ageと違って retainという記述があります。このretainについては次の節で説明 しますが、こちらは基本型ではなく、オブジェクトへの参照がプロパティ です。オブジェクトを引数に取るメソッドについては、 原則 としてこの ように代入時の動作を既定するオプションとしてretainを宣言するか、 あるいはcopyによってオブジェクトそのもののコピーを記録することを 行います。単なる参照の代入では、オブジェクトの開放との兼ね合いに 問題が出る 可能性があるので、

出たぁぁ!原則!可能性!

真面目な話、 この人の文章を初心者が読んだら混乱するだけ だぞ。 そういう意味ではAmazonの書評は全く正しいな。これは確かに初心者向けじゃない (むろん玄人向けでもないが)。 プロパティにしても、これは他言語からの概念で、オブジェクト指向含めて周辺的な知識を 網羅的に持っている人間には何が言いたいかわかるだろうけど、そんな人は読む必要もないだろ。

_ 俺ならこう書く!プロパティの説明

ちなみに手元のLinux gccには@propertyが無かったし(え?)言語仕様も知らないで(え?) propertyの説明を書いてみる。当然間違ってるだろう(笑)。

  1. オブジェクト指向の利点の一つに「隠蔽」がある
  2. オブジェクト内(インスタンス内)のアクセスする必要のないデータにはアクセスできないようにする
  3. 逆に、必要なデータにはアクセサ(アクセス関数,アクセスメソッド)経由で値を操作するという基本概念
  4. アクセサは、値の境界値チェックしたりもできるから、 単なる代入よりも、安全性が高まるよ
  5. でも全部のデータにアクセサを用意すると、それだけで関数てんこ盛りになって打つのがたるいよ
  6. しかも、スレッドセーフを考えると、関連する操作関数間で値を変更する際に排他制御を考えなくちゃならないので、値を操作するだけのつまんない関数なのにけっこう神経を使うよ
  7. 誰かなんとかしてくれないかなあ?
  8. Objective-Cではプロパティという宣言でコンパイラが勝手に作ってくれるようにしたよ

ここまでが導入。

  1. Objective-Cの場合は、変数宣言する段階で@propertyってつけるとプロパティになるよ
  2. さらに実装の部分は@synthesizeって書くと自動的にアクセサの実装を作ってくれるよ
  3. プロパティの書式HOGE.PIYOで読み書きするとき、自動的にアクセサであるゲッタとセッタが呼ばれるよ
  4. デフォルトではreadwrite属性だけど、 絶対書かないと分かっている場合は、 readonlyって書くとコンパイラがチェックしてくれるよ
  5. ゲッタとセッタは自分で定義することもできるよ。でもそれなら最初からメソッド記述しても大して差はないけどね。これは後で少し説明しようか。
  6. スレッドセーフに関しては未記述だとデフォルトでONだけど、 絶対にアクセス競合が起きないとわかっている時は nonatomic属性を付けるとOFFにできるよ
  7. アクセサの デフォルトは代入属性 assignだ。Cでも用意されている整数型などのプロパティ管理ではこれで十分だ。set(int v) { hoge_ = v; }ということね。
  8. しかし動的オブジェクトの場合はassginだと困るよね。Cで言えばchar *hoge = malloc(13);したポインタ変数にhoge = malloc(25);したらメモリリークだよね?
  9. assign属性の代わりにretain属性を付けると、リファレンスカウントによる参照管理を行ってくれるよ。つまり必要の無くなった(どのオブジェクトからも指し示されていない)オブジェクトは回収される。前期でいうとmalloc(13)の方は勝手に回収されるんだ。
  10. retain属性の場合は渡されたオブジェクトをそのまま管理する。つまりアクセサをコールした上位で 開放してはいけない。
  11. しかし時にはコールしたオブジェクトのコピーを保存しておいきたい場合がある。例えば辞書みたいなものを蓄積するテーブルオブジェクトを考えたときは、アクセサ内部でオブジェクトのコピーをしてくれるとありがたい。
  12. そんな時はretainの代わりにcopy属性をセットするよ。

以上がプロパティの仕様。

結局のところ「ただ単に文字列を内部でコピーして保持するセッタ」を「Cでオブジェクト指向っぽっく書く」と、以下のようなコードになるだろう。これを@property(copy)と@synthesizeで終わらせてしまえるのだから、メンバ変数が多くなればなるほどObjective-Cが有利なのは疑いない。 エラー処理がほとんどないのと、スレッドセーフの手段がグローバルロックなのは手抜きである。申し訳ない。

static CRITICAL_SECTION lock_;

void setFamilyName(id obj, char *newname)
{
  int len;
  char *tmp;

  if (obj == NULL || newname == NULL) return;

  ENTER_CRITICAL_SECTION(lock_);
  len = strlen(newname);
  tmp = (char *)malloc(len + 1);
  if (tmp == NULL) {
    LEAVE_CRITICAL_SECTION(lock_);
    return;
  }
  strcpy(tmp, newname);
  if (obj->name != NULL) {
      free(obj->name);
  }
  obj->name = tmp;
  LEAVE_CRITICAL_SECTION(lock_);
  return;
}

まあ正確性に関してはマジ墓穴というか

誤植だらけの本書いてたバカが何をほざく

という感じで赤面状態なわけだが、久々に高い本で腹が立ったので書いてみた。


2001|04|
2006|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|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|03|04|05|10|

[BANNER]
このサーバーをもう12年も維持しているかと思うとめまいがしますよ。
ツッコミ機能は、ハンドル名が完全日本語じゃないと登録できません。
また、本文にURLが含まれていても登録できません。
いずれもSPAM対策です。
[Panda Papanda]
2009年
9月
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

[Papanda]  [Kuma]  [Tomorin]  [Iron]  [Eiza]  [Dokkin]  [Honya]  [Zyou]  [Tsuyo]  [Bike]  [KoeBBS]  [Chukei]  [portal]  [tvmatome]  [KaoPaku] 

訪問者数:(11777+2560143)