MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第347号

2009-06-23

目次

  • りんご味Ruby         第49回  藤本 尚邦
  • 藤本裕之のプログラミング夜話   #162
  • 高橋真人の「プログラミング指南」  第160回

MOSA新会長ご挨拶           有限会社オッティモ 小池 邦人

iPhoneが登場して以来、そのデバイスやシステム、もしくはビジネスモデルに対して様々な場所で色々な評価がなされています。その中で、あまり大きくは取り上げられていないのですが、「Mac + Cocoa + Objective-C」を経験したデベロッパーの数が格段に増えたという事実はかなり重要でしょう。Apple社の発表によると、本年度のWWDCは早々に満員御礼となり(参加者5,200人)、その60%が初めての参加者だったそうです。また、iPhone SDKのダウンロード数も100万を超えました。

iPhone登場以前と比較し、Apple社製品にからむデベロッパーの数は10倍以上になったそうです。Apple社は、MacやiPhoneを中心としたエコシステムに対して大きな基盤を得たことになります。つまり、iPhoneアプリだけではなく、iPhone+Macソリューション構築時のMac OS X用ソフト、iPhone用周辺機器のソフト、そしてApple社が次に準備しているだろう「まったく新しいデバイス」用ソフトなどなど、それらの開発を担うことができるデベロッパーを一定数確保したことになります。

その一方で、iPhoneアプリの開発は、手軽に作品発表ができるApp Storeの存在や、多くの関連書籍の出版のおかげで、あの懐かしいHyperCardの様な雰囲気も醸し出しています。確かに、そこまで簡単ではないのですが、プログラミングという「創造の結果」を手軽に体験できるツールとしては、久しぶりに登場した大物です。そのため、iPhoneユーザの中には、アプリ開発にチャレンジしてみようと思い立ったプログラミング初心者の方も多いようです。また、往年のプログラマーの中には、密かに「現役復帰」を画策する人も少なくありません(笑)。

MOSAは、職業デベロッパーの方々だけではなく、プログラム初心者や学生の方の参加も大歓迎です。iPhone登場により、久しぶりに目が向けられた「プログラミングの楽しさや面白さ」を、さらに多くの方々と共有できればと考えています。そのためには、技術セミナーや各種イベント、そしてWebやオフラインによる会員同士のコミュニケーションを積極的にサポートしていきます。スタッフ一同「MOSA会員が作り上げるMOSA」を目標にがんばりたいと思いますので、会員の皆様のご協力、よろしくお願い致します。

好きこそ物の上手なれ!     MOSA会長 有限会社オッティモ 小池邦人

りんご味Ruby   第49回  藤本 尚邦

iPhone 3.0 がリリースされましたね。iPhoneとRubyといえば、森琢磨さんがRuby と RubyCocoa を iPhone に移植した iPhone RubyCocoa を公開しています。iPhone RubyCocoa には、リモートirbという機能が組み込まれています。この機能により、実行中のiPhoneアプリケーションのオブジェクトシステムに対して、リモートコンピュータ(リモートプロセス)からtelnet経由で、irbによるアクセスが可能です。

今回から、この iPhone RubyCocoa をiPhoneアプリケーションの開発に活用する方法を考えてみることにします。

■ iPhone RubyCocoa のダウンロード

iPhone RubyCocoa のソースコードは、githubで公開されています。githubというのは、分散型バージョン管理システム git によるソースコード管理を提供しているホスティングサービスです。では、github上の iPhone RubyCocoa のページ:

http://github.com/takuma104/iphone-rubycocoa/tree/master

から iPhone RubyCocoa のソースコードを入手しましょう。

git コマンドを使う場合には:

 $ cd どこか作業用のディレクトリ
 $ git clone git://github.com/takuma104/iphone-rubycocoa.git
 $ open iphone-rubycocoa

でソースコードをダウンロードできます。

といっても、OS X 10.5 には git がインストールされていませんので、git を使っていない(インストールしていない)場合は、上記ページの download ボタンを押して、zip形式(あるいはtar形式)のファイルをダウンロードして展開してください:

 $ unzip takuma104-iphone-rubycocoa-ユニークID.zip
 $ mv takuma104-iphone-rubycocoa-ユニークID iphone-rubycocoa
 $ open iphone-rubycocoa


(注: 「ユニークID」の部分には、ダウンロード時のソースコードのリビジョンを表す16進数番号が入ります)

■ Xcode でビルド

では、最新の Xcode 3.1.3 を使ってビルドしてみましょう。Xcodeのプロジェクトファイル rubycocoa4iphone.xcodeproj を開いて、そのままビルドしてください。たくさんの警告(私のところでは28個)がでましたがリンクは通っているので、警告の解決は後回しにしてとりあえず実行してみます。iPhoneシミュレータの画面に「hello RubyCocoa world」と表示されたでしょうか?

■ リモートirb

iPhone RubyCocoa のリモートirb機能は、デフォルトでは(おそらくセキュリティ上の理由から)機能しないようにコメントアウトされています。しかし、この機能こそ、iPhone RubyCocoa で一番使いたいところでもありますから、使えるようにしてみましょう(注: この機能はリモートコンピュータに対してIP接続のポートを公開することになるので、その点注意してください)。プロジェクト内のmain.rbファイルの 3,4行目:

 # require 'remote_irb'
 # RemoteIRB.new(6000).start

の部分のコメントを外して:

 require 'remote_irb'
 RemoteIRB.new(6000).start


にします。これをビルドして実行しましょう。先ほどと同じく、iPhone シミュレータの画面に「hello RubyCocoa world」と表示されたでしょうか(注: ここでシミュレータ内のiPhoneアプリケーションが落ちてしまう場合があるのですが、それについては後述します)。さらに、Xcode のデバッガコンソールを見ると:

 [remote_irb] listening on 192.168.xxx.xxx:6000
 #
 #
 #

と表示されています。 IPアドレス 192.168.xxx.xxx のポート番号6000で接続
を待ち受けているということなので、telnet で接続してみましょう:

 $ telnet 192.168.xxx.xxx 6000
 Trying 192.168.xxx.xxx...
 Connected to 192.168.xxx.xxx.
 Escape character is '^]'.
 >> 


どうやら、iPhoneシミュレータ上で動く irb に接続することができたようです。
さっそく、アプリケーションオブジェクトにアクセスしてみます:

 >> app = OSX::UIApplication.sharedApplication
 => #
 >> view = app.keyWindow.contentView
 => #
 >> view.class
 => OSX::UILabel

contentViewには UILabelがセットされているようです:

 >> view.text.to_s
 => "hello RubyCocoa world"

UILabelのテキストと背景色を変更してみましょう:

 >> view.setText Time.now.to_s
 => nil
 >> view.setBackgroundColor OSX::UIColor.blueColor
 => nil


というような感じで、実行中のiPhoneアプリケーションのオブジェクトを操作することができました。

ところで、このプロジェクトは、iPhone Simulator 2.2.1 向けになっています。
ここは 3.0 で動かしたいところですが、残念ながらリンクエラーになってしまいます。コンパイル時の警告も含めて、次回は 3.0 で動かせるように修正することにします。

■ (補足) ビルドしたiPhoneアプリケーションが落ちてしまう場合の対策

iPhone上のRubyがkconvライブラリを要求して落ちてしまうようで、言語の設定(localeなど)が関係しているようですが、これを書いている時点でははっきりと解決はできていません。私のところでは、iPhoneシミュレータを、XcodeからではなくFinderから起動して、ビルドしたiPhoneアプリを起動したら立ち上がるようになりました。

■ 参考URL

iPhone で Ruby/RubyCocoa を動かしてみた
http://d.hatena.ne.jp/takuma104/20090225/1235584788

iphone-rubycocoaで、実機動作中のアプリをリモートから動的に変更する
http://d.hatena.ne.jp/takuma104/20090301/1235927945

github の iPhone RubyCocoa ページ
http://github.com/takuma104/iphone-rubycocoa/tree/master

藤本裕之のプログラミング夜話 #162

 承前……と言って皆さんWWDC前にモサ伝で読んだことなど憶えてないかも知れないので(なに憶えてなくても恥ぢゃない、書いてるオレが今前回のを読み返してからこれを書き始めてんだから)、「前回までの『24』は……」的にちょいとおさらいをする。まず我々は以下のような真実を確認した。

「ソフトウェア技術者は昔も今も『高度で専門的な知識や経験を要する』職業である」
 
 しかるに現状はこうである。

「ソフトウェア技術者は『高度で専門的な知識や経験を要する』職業にふさわしい扱われかたをしていない……安くコキ使われている」

 で、それはなんでだ? という設問に対する粉砕すべき仮説1として以下のものを提示したところまで、である。

仮説1:ソフトウェア技術者の待遇が悪いのは受給のバランス、つまり供給が過剰だからである。「高度で専門的な知識や経験」も数が増えれば安くなるの
が当然やんけ。

 で、上の仮説どー思います? その通りだと思いますか? ここで読者処刑……ハリツケ獄門食らってどうする、諸兄に納得されてしまうとオレも立つ瀬がないんだが、どうですか、実感としてこの仮説に首肯できるかたはおられましょうか。ワタクシはと言えば到底首肯できない、バン!(机を叩いた)。

 なんつかな、ひどく卑近かつ個人的怨念びしばしの話をさせてもらうと、そんなに「高度で専門的な知識や経験」を持ったヒトが増えて安く使えるようになってるのなら、あの時オレはもっと楽できたはずだと思い起こし、枕をくやし涙で濡らすような(濡らしやしないがね)仕事というのが数多あるのである。

 オレ思うに、仮説1はこう書き換えられるべきではないか。

仮説1(改):ソフトウェア技術者の待遇が悪いのは、「需要」に対して業界が、実際には「高度で専門的な知識や経験」を持たない人材までを「供給」したことに起因する「見かけの供給過剰」が原因である。

 どっすか? これ、裏を返せばあの「IBM/システム360の父」フレデリック・P・ブルックスJrがその名著「人月の神話」の中で喝破した問題そのものである。読んでないヒトのために(読んだ方がいいよ)その部分だけかいつまむと、ブルックスはこう言ってる。

「コストは人数と月数の積(人月)である。が、進捗はそうではない」

 もう涙が出るほど簡潔でしょ?

 そして彼は、「コスト(人月)」と「進捗」を混同して「人月を仕事の大きさを測る単位として使う」ことを「人月の神話」として戒めてる。……んだけど、この本が最初に出版された1975年からもう30年以上経っているにも関わらず、そして日本人の「教科書ダイスキ体質」にも関わらず、この悪弊だけは改善されずに残っているのである。

 でもこのブルックスの言葉、他の仕事に当てはめると別に特段珍しいことを言ってるわけではないのだ。例えばあなたが家を建てるとする。どうせ例えばの話なんだから田園調布あたりに300坪くらいの土地があり、建築資金も潤沢にあるとしよう。

 友人の建築家(そういう金持ちにはたいがい建築家の友達がいる)に図面をひいてもらい、腕のいい工務店を紹介してもらう。その時工務店が持ってくる見積もりは「大工何人が何ヶ月仕事しますからいくらです」ぢゃなくて「仮設工事いくら、基礎工事いくら、地盤改良工事いくら……」ですよ。

 次回より、なぜ日本のソフトウェア産業では「人月の神話」がまかり通るのかちゅうコトを追求しよう。
                       (以下次回 2009_06_19)

高橋真人の「プログラミング指南」第160回

これから始めようとする人へ(11)

 皆さんこんにちは、高橋真人です。今回はリファレンスカウントという考え方についてのお話です。
 前回、「次回はretainカウントについて説明します」と予告しましたが、Cocoa特有の用語であるretainカウントを説明する前に、もっと一般的な概念の方を説明しておく方がいいと思いますので、先にリファレンスカウントを説明します。

 さて、malloc()によってヒープ領域から動的に確保したメモリーをfree()で解放するということについては前にお話をしましたが、実際のプログラムにおいては、この動的に確保されたメモリー領域が複数の個所から参照されるために話がややこしくなり、「解放のし忘れ」や「既に解放済みの領域にアクセスしようとする」といったバグの温床となります。
 具体的に見てみましょう。

// バグあり、注意!
01: #include 
02: #include 
03: 
04: int main (void)
05: {
06:     int *a = NULL, *b = NULL;
07: 
08:     a = malloc(sizeof(int));
09:     *a = 10;
10:     printf("*a = %d\n", *a);
11:     b = a;
12:     ++(*b);
13:     printf("*b = %d\n", *b);
14:     free(b);
15:     printf("*a = %d\n", *a);
16: 
17:     return 0;
18: }


 intを指すポインタaとbを用意し、aに対して動的に確保したメモリ領域を割り当てます(6、8行目)。その領域に10という値を書き込んで、結果を確認します(9、10行目)。
 次に、bにもaの指している先をコピーし、bを経由して書き込んであった値をインクリメント(値を一つ増やすこと)します(11、12行目)。bの値を確認して(13行目)、bの指している先を解放します(14行目)。そして、aの指している先の値を確認する(15行目)というのが、このプログラムでやっていることです。
 さて、どこにバグがあるのか、お分かりですか?

 その答えは、14行目と15行目、確保した領域を解放してしまったあとでaを経由して値にアクセスしているところです。(実際に上記のコードを自分で試してみられた方、プログラムが落ちることはなかったかもしれませんが、それでこのプログラムにバグがないということにはなりません。理由を説明するのは話の本筋から外れるので省略しますが。)
 「あれ? 解放しているのはbだから、aの方は大丈夫なのでは?」と思われた方、11行目の代入文でbにコピーされているのは、領域を表すアドレス値であり、aもbも同じ場所を指している(つまり、aとbの値は同じである)ことをしっかりと認識してください。
 つまり、上記のコードでは意図的に混乱を引き起こすために(笑)、bを使って領域の解放を行っていますが、free(a)と書いてもfree(b)と書いても、11行目が実行された後であれば、a、bそのものの値が変更されない限りにおいて両者は同じ意味を持つのです。

 さて、上記の例をリファレンスカウントという観点からもう一度見てみます。
 まず、malloc()により確保された領域を何らかのオブジェクトだと言い換えてみます(今回は、オブジェクトの実体は単なるintの値ですが)。そして、このオブジェクトは、aというポインタによって参照されていることになります。
 bにaを代入するということは、bもまたこのオブジェクトに対する参照を得るということを表します。
 さて、件のオブジェクトはこの段階でaとbという二つのポインタから参照されています。この状態をリファレンスカウントが2であると表現します。
 a、b二つのポインタがこのオブジェクトを参照している以上、たとえばaにとってもう必要なくなったからと言って、勝手にこの領域を解放してしまうと、bの立場がなくなります(笑)。

 aにとって、この領域への関心がもうなくなったならば、ここはいきなりfree()を呼び出してしまうのではなく、単に

a = NULL;

とでもして、もうその領域を指すことをやめるだけにとどめておけばいいのです。この時点で件のオブジェクトを参照しているポインタはbだけですので、リファレンスカウントは1となります。
 そして、もしbにとってもこのオブジェクト不要となった場合、このオブジェクトをいよいよ解放するべきときが来たということになります。もちろん、それまでの間に別のポインタが新たにこのオブジェクトに対する参照をすることがないということが前提です。
 ちなみに、この場合においても

b = NULL;

とするのみで、free()を呼び出すことなくbがオブジェクトへの参照を放棄してしまえば、最早オブジェクトを参照するものが一つもない状態になるため、このオブジェクトの格納されている領域を解放することは永久にできず、いわゆるメモリーリークが発生することとなります。

 さて、今までのお話で「リファレンスカウント」という言葉を使って、「今、このオブジェクトを参照しているポインタはいくつ」ということを数えていましたが、それをしていたのは、あくまでこのコードを見ている人間の側でしかありませんから、コードがもっと複雑になって、「えっと、ここでこのポインタが参照を得て、この部分でこっちのポインタが参照を放棄しているから…」などといちいちやっていたら必ず間違えが起こりますし、何よりも面倒この上ありませんよね。
 そこで、このリファレンスカウントという考え方を実際にコードの中に組み込んで、プログラムに自動で管理させようというのが、本来のリファレンスカウントの考え方です。

 次回は、簡単なプログラムで実際にこのリファレンスカウントの使い方を見ていこうと思います。

◇MOSAからのお知らせと編集後記は割愛します◇

 

 MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2009 MOSA. All rights reserved.