<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
    <channel rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/">
        <title>Cocoa はじめの一歩</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/</link>
        <description>Cocoaを全くの0から学ぶための資料を提供します。練習問題をときどき更新します。</description>
        <items>
            <rdf:Seq>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer12.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise12_2.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise12_1.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer11.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise11.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer10.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise10.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer9.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise9.html"></rdf:li>
                <rdf:li rdf:resource="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer8.html"></rdf:li>

            </rdf:Seq>
        </items>
    </channel>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer12.html">
        <title>練習問題12</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer12.html</link>
        <description>　解答編です。といっても難しいことはそれほどなかったと思いますが。まずデバッグをする上では「アクティブなビルド設定」をDebugにしてからビルドする、ということを忘れないでください。ブレークポイントで止まらない、バグだ！と焦る前にビルド設定を確認しましょう。&lt;br />
　今回仕込んだバグは以下の三点です。&lt;br />

&lt;ol type="1">
&lt;li />BMI計算の結果がおかしい&lt;/li />
&lt;li />身長の値が起動するたびにもとに戻ってしまう&lt;/li />
&lt;li />BMIが18より低い時Dockのアイコンが青に変わるはずが変わら</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-10-19T13:47+09:00</dc:date>
        <content:encoded>　解答編です。といっても難しいことはそれほどなかったと思いますが。まずデバッグをする上では「アクティブなビルド設定」をDebugにしてからビルドする、ということを忘れないでください。ブレークポイントで止まらない、バグだ！と焦る前にビルド設定を確認しましょう。&lt;br />
　今回仕込んだバグは以下の三点です。&lt;br />

&lt;ol type="1">
&lt;li />BMI計算の結果がおかしい&lt;/li />
&lt;li />身長の値が起動するたびにもとに戻ってしまう&lt;/li />
&lt;li />BMIが18より低い時Dockのアイコンが青に変わるはずが変わらない&lt;/li />
&lt;/ol />　&lt;br />
&lt;br />
　全てチェックしましたか？見落としがあったらもう一度調べなおしてください。公開する前にこのようにバグが無いかをいろいろチェックするのは結構大変な作業です。知合いに試しに使ってもらうというのも大切です。また公開後にたまにバグの指摘があるので、そういうときはなるべく早く修正するように努力しましょう。&lt;br />
　また当然のことですが、プログラムの構造についてある程度理解していないとうまくデバッグすることができません。上記2のバグの原因を調べるために、例えばBMIの計算をする部分にブレークポイントを仕掛けても意味が無い、ということは分かると思います。正しく値が保存されているか、保存された値が正しく読み込まれているか、「saveUserDefaults」と「loadUserDefaults」をチェックしなければなりません。&lt;br />
&lt;br />
　ということでまず2の解説。保存が正しく行われているかをチェックするためにまず「saveUserDefaults」を見てみると、特に問題は無さそうです。「loadUserDefaults」の方にブレークポイントを仕掛けて動作をチェックしてみましょう。何度実行しても&lt;br />
&lt;pre />&lt;code />&lt;div id="source">height=[aDefault floatForKey:@"height"];&lt;/div />&lt;/code />&lt;/pre />&lt;br />
のデータの読み込みには行かず、&lt;br />
&lt;pre />&lt;code />&lt;div id="source">height=[heightField floatValue];&lt;/div />&lt;/code />&lt;/pre />&lt;br />
に行ってしまうはずです。どうもifの分岐に問題があるようです・・・&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_11.png">&lt;/div />&lt;br />
&lt;br />
　原因がわかりましたか？&lt;br />
&lt;br />
　ちなみに初期設定フォルダに入っている「learnCocoa.sekn.CalcBmi.plist」という初期設定ファイルをダブルクリックすると、「Property List Editor」というアプリで初期設定の保存内容を覗くことができます。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_12.png">&lt;/div />&lt;br />
&lt;br />
　これを覗けば身長が正しく保存されているか、それとも保存に失敗しているのかを確認することができます。&lt;br />
&lt;br />
&lt;br />
　1のBMIの計算がおかしいというバグは見つけやすいと思いますので解説は省略。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (IBAction)changeBMI:(id)sender;
- (IBAction)changeHeight:(id)sender;
- (IBAction)changeWeight:(id)sender;&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　あたりにブレークポイントを置いて、計算の様子を順番にチェックしてください。&lt;br />
&lt;br />
&lt;br />
　3のアイコンの問題は当然「setDockIcon」メソッドを調べます。ステップオーバーで一行ずつ実行していくと・・・&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_13.png">&lt;/div />&lt;br />
&lt;br />
　青アイコンの読み込みの所へは正しく進んでいます。ところが・・・&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_14.png">&lt;/div />&lt;br />
&lt;br />
　読み込んだNSImageへのポインタである変数「anIcon」が「0x0」になっています。「0x0」とは16進数で0のこと、NSImageのインスタンスが「無い」ということです（例えば0x123なら16進数で123、10進数では291のことです。ただしポインタの値はメモリのアドレスであり10進数に戻しても意味はありません。「0x0の時はオブジェクトが無い」ということだけ覚えておいてください）。つまり&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">anIcon=[NSImage imageNamed:@"blue.png"];&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　でアイコンファイルをうまく読み込めなかった、ということです。なぜ読み込めなかったのかは自分で調べてみてください。&lt;br />
&lt;br />
&lt;br />
　この辺で解答編は終わります。効率よくデバッグするには、解説しにくいノウハウや、どこに問題があるかを見つける勘などいろいろな要素があります。いろいろなアプリを作って、たくさんデバッグをしてみるのが一番です。&lt;br />
&lt;br />
　一通りそれらしいアプリケーションが完成し、デバッグの方法も学んだので、しばらく続いてきた「CalcBMIみたいなのを作ってみよう! 」シリーズはここまでで終わりにします。長々とやってはきたものの、プログラミングの工程そのものはそれほど多くなく、簡単なものならかなり手軽に作れるということがわかっていただけたのではないでしょうか？&lt;br />
　次回からは「バインディング」を使ってもっと楽にプログラムを書く手法を紹介したいと思います。</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise12_2.html">
        <title>練習問題12</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise12_2.html</link>
        <description>　次に右上の変数表示欄に注目してください。以下は「loadUserDefaults」の最初の行で止めた状態です。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_6.png">&lt;/div />&lt;br />
&lt;br />
　Localsの下にはaDefaultという変数が表示されています。このLocalsには現在表示している関数やメソッドのローカル変数の一覧が表示されます。このメソッドの中ではNSUserDefaultsのインスタンス（へのポインタ）のaDefaultという変数一つ</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-10-19T10:43+09:00</dc:date>
        <content:encoded>　次に右上の変数表示欄に注目してください。以下は「loadUserDefaults」の最初の行で止めた状態です。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_6.png">&lt;/div />&lt;br />
&lt;br />
　Localsの下にはaDefaultという変数が表示されています。このLocalsには現在表示している関数やメソッドのローカル変数の一覧が表示されます。このメソッドの中ではNSUserDefaultsのインスタンス（へのポインタ）のaDefaultという変数一つだけ使っているので、それが一つだけ表示されているわけです。aDefaultはポインタなので値の欄にはメモリアドレスが表示されます。&lt;br />
　次にArgumentsの方を見ると「self」という変数があります。これはこのメソッドを実行しているオブジェクトそれ自体のポインタ、つまりBMIControllerのインスタンスです。selfの中身を見てみましょう。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_7.png">&lt;/div />&lt;br />
&lt;br />
　見知った変数名が並んでいますね。BMIControllerのインスタンス変数の名前が並んでいます。BMIController.hをチェックしてみてください。「IBOutlet id」型のオブジェクトはそのオブジェクトへのポインタが、float型の変数はその値が表示されます。まだ数値を初期化していないので、height、weight、bmiの値はそれぞれ0のはずです。&lt;br />
　では五行ほど実行してみましょう。「if([aDefault floatForKey:@"weight"])」の手前まで実行します。三回ステップオーバーボタンを押せばOKのはずです。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_7.png">&lt;/div />&lt;br />
&lt;br />
　heightの値が初期化されて変わったでしょうか。値が変わるとわかりやすいように赤字で表示されます。上記のスクリーンショットではheightは初期設定からデータが読み込まれて183.059204になりました。同様にweightの方も初期化されることを確認してください。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_8.png">&lt;/div />&lt;br />
&lt;br />
　各変数の内容（特にオブジェクトの概要）をコンソールに表示することができます。調べたい変数を選択して右クリックで「説明をコンソールに表示する」を選択すると、選択中の変数の説明がデバッガコンソールに表示されます。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_9.png">&lt;/div />&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_10.png">&lt;/div />&lt;br />
&lt;br />
　NSArrayやNSDictionaryなどのオブジェクトの場合中身が表示されますし、少なくともオブジェクトがどのクラスのインスタンスか程度はわかります。オブジェクトの場合、あたいにポインタしか表示されないことが多いので、この機能で中身をチェックすることが重要になります。&lt;br />
&lt;br />
　デバッグで一番重要なのはこのような機能です。細かく説明していったらきりがないのでとりあえずこの辺で終わりにします。&lt;br />
&lt;br />
　最後に今回の課題です。まず&lt;a href="http://samples/Exercise12.zip">こちら&lt;/a>からサンプルをダウンロードしてください。いくつかバグが仕込んでありますので、ソースコードの比較をするのではなく、デバッガを使ってバグを修正してみてください。&lt;br />
&lt;br />
&lt;div align="right">解答は&lt;a href="http://answer12.html">こちら&lt;/a>　　　&lt;/div />&lt;br />
</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise12_1.html">
        <title>練習問題12</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise12_1.html</link>
        <description>　今回はプログラミングをする上で必須のツール、デバッガの使い方を簡単に説明します。デバッガはプログラムのバグを見つけるためのプログラムで、ソースコードを一行ずつ実行したり、特定の箇所で止めたり、変数の状態を調べたりすることができます。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_1.png">&lt;/div />&lt;br />
&lt;br />
　まずデバッガを起動するにはプログラムをデバッグできる状態でビルドする必要があります。Xcodeでプロジェクトを開いたら「プロジェクト」メニュ</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-10-19T10:35+09:00</dc:date>
        <content:encoded>　今回はプログラミングをする上で必須のツール、デバッガの使い方を簡単に説明します。デバッガはプログラムのバグを見つけるためのプログラムで、ソースコードを一行ずつ実行したり、特定の箇所で止めたり、変数の状態を調べたりすることができます。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_1.png">&lt;/div />&lt;br />
&lt;br />
　まずデバッガを起動するにはプログラムをデバッグできる状態でビルドする必要があります。Xcodeでプロジェクトを開いたら「プロジェクト」メニューの「アクティブなビルド構成を設定」で「Debug」を選択してください。これでビルドの際、デバッガで利用できる形でアプリケーションがビルドされます。逆に一般に配布するためのアプリケーションを作る場合は「Release」を選択してビルドしてください。選択したらツールバーのボタンから「ビルドとデバッグ」をクリックします。これで自動的にアプリケーションがビルドされデバッグが始まります。&lt;br />
　デバッグが始まるとデバッガウィンドウが開きます。このウィンドウで様々デバッグ作業を行います。そのままではおそらく何も起こりませんので、「ブレークポイント」をセットしてプログラムの動作を止めてみます。メソッド「awakeFromNib」の中で「loadUserDefaults」を呼び出しているところに移動し、左側の行番号が表示されているところをクリックしてください。紺色のマークが表示されるはずです。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_2.png">&lt;/div />&lt;br />
&lt;br />
　これがブレークポイントです。ブレークポイントを設定しておくと、デバッグの際プログラムがそこまで実行されたら自動的にプログラムの実行が止まります。「ビルドとデバッグ」をクリックして実行してみましょう。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_3.png">&lt;/div />&lt;br />
&lt;br />
　上のスクリーンショットのように途中で実行が止まるはずです。まずウィンドウの下部ですが、現在実行中のコードが表示されます。青く強調表示されている部分でプログラムの実行が止まっています。スクリーンショットでは「loadUserDefaults」のところが強調されていますが、「loadUserDefaults」は&lt;b />まだ実行されていません&lt;/b />。実行される前の段階です。ウィンドウ右上はプログラムの中の変数の名前と値が一覧で表示されます。これについては後で説明します。左上はコールスタックといって、関数やメソッドの呼び出しの階層が表示されます。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_4.png">&lt;/div />&lt;br />
&lt;br />
　これは下から順番に上に向かって関数やメソッドが呼び出された、ということを示しています。全てのCプログラムはmain()関数から始まる、ということを学びましたが、一番下、つまり関数呼び出しの一番最初は確かにmainになっています。main()関数はその中でNSApplicationMainという関数を呼び出し、NSApplicationMainはNSBundleオブジェクトの「loadNibNamed:owner:」というメソッドを呼び出し、それは「loadNibFile:externalNameTable:withZone:」というメソッドを呼び出し・・・と続いて最後に「awakeFromNib」が呼び出された、ということがわかります。あるメソッドがいったいどういう敬意で呼ばれたのかを調べるときなどに有用な情報です。&lt;br />
&lt;br />
　ウィンドウの表示を一通り眺めたらツールバーの「ステップイン」というボタンを押してください。強調表示は「loadUserDefaults」のメソッドの中に移動して止まります。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise12_5.png">&lt;/div />&lt;br />
&lt;br />
　ステップインというのは今止まっている行の関数の中に入れ、という指示です。それに対して「ステップオーバー」をクリックすると「loadUserDefaults」メソッドを実行して次の行（ここでは「calcBMIAndSet」）で止まります。つまりこれから実行しようとしている処理の中に入って詳しく調べたいときはステップイン、ただ実行するだけのときはステップオーバーを選択します。では「ステップアウト」とは何かというと、現在実行中のメソッド（関数）の残りを実行して上に出ろ、ということです。例えば「loadUserDefaults」の中をステップオーバーで半分くらい調べたあとステップアウトをクリックするとawakeFromNibの「calcBMIAndSet」のところまで進みます。また「続ける」ボタンを押すと一行ごとの実行をやめて普通に処理を進めます。次のブレークポイントがあればそこまで進んで止まりますし、無ければそのままアプリケーションの実行を続けます。文章で書くとわかりにくいので、実際にボタンをいろいろ操作してどういう風に動くのか試してみてください。&lt;br />
&lt;br />
</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer11.html">
        <title>練習問題11</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer11.html</link>
        <description>　では解答編です。なんだか難しそうなことをしそうな感じがしたかもしれませんが、実際のところはものすごく簡単です。まずはDockの表示をBMIの結果にあわせて切り替えるメソッドから。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (void)setDockIcon
{
  NSImage  *anIcon;
  if( bmi &lt; kUnderweightMax )
    anIcon = [NSImage imageNamed: @"blue.png"];
  else if( bmi &lt; kNorma</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-10-19T10:35+09:00</dc:date>
        <content:encoded>　では解答編です。なんだか難しそうなことをしそうな感じがしたかもしれませんが、実際のところはものすごく簡単です。まずはDockの表示をBMIの結果にあわせて切り替えるメソッドから。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (void)setDockIcon
{
  NSImage  *anIcon;
  if( bmi &lt; kUnderweightMax )
    anIcon = [NSImage imageNamed: @"blue.png"];
  else if( bmi &lt; kNormalWeightMax )
    anIcon = [NSImage imageNamed: @"white.png"];
  else if( bmi &lt; kOverweightMax )
    anIcon = [NSImage imageNamed: @"yellow.png"];
  else
    anIcon = [NSImage imageNamed: @"red.png"];
  
  [NSApp setApplicationIconImage: anIcon]; 
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　計算結果のBMIの値を見て対応するイメージを取り出し、それを「setApplicationIconImage:」メソッドでセットしてあげるだけです。BMIの値の判定のところで「k○○」という単語を使っていますが、これはヘッダ「BMICalculator.h」の方で定義します。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">#define  kUnderweightMax  18
#define  kNormalWeightMax  25
#define  kOverweightMax  30&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　この#define命令については「&lt;a href="http://clesson2.html">C言語補習2&lt;/a>」を参照してください。#defineしたのにあわせて「setValues」メソッドも少し書き換えました。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">  if(bmi &lt; kUnderweightMax)
    [alertField setStringValue: NSLocalizedString(@"too thin",@"") ];
  else if(bmi />kNormalWeightMax)
    [alertField setStringValue: NSLocalizedString(@"too fat",@"") ];
  else
    [alertField setStringValue: @""];&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　このように#defineを使うことで、例えば将来痩せ過ぎの基準値が18から19に変わったとしても、#defineで定義してある部分一カ所を変えるだけで済み、ソースコードの中の18を探しまわって変更する必要は無くなり便利です。&lt;br />
&lt;br />
　さて、あとは作った「setDockIcon」メソッドを適当なタイミングで呼び出してやればOKです。具体的には「setValues」で計算結果をウィンドウに表示した後にDockの表示を書き換えれば良いでしょう。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (void)setValues
{
  [bmiField setFloatValue:bmi];
  [bmiSlider setFloatValue:bmi];

  //略  
 else
    [alertField setStringValue:@""];

  [self setDockIcon];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　これで完成です。そうそう、新しく作ったメソッド「setDockIcon」の定義をヘッダに追加するのも忘れないように。&lt;br />
　完成品サンプルを&lt;a href="http://samples/Exercise11.zip">こちら&lt;/a>に置いておきます。&lt;br />
&lt;br />
&lt;br />
　今回実装した機能は一見作るのに時間がかかりそうに思われるかもしれませんが、方法さえわかってしまえば後はすごく簡単だ、ということがわかっていただけたのではないかと思います。プログラムの基本構造というのは結局条件分岐と繰返しだけで、それ以外の大変な作業というのは、APIとしてOSから提供されている機能にどんなものがあるのか、どうやって使えば良いのかを調べることだったりします。最近はCocoaに関する日本語の情報も大分増えてきたのでそういうページをチェックしたり、英語のドキュメントを面倒くさがらずに読むことが、プログラミング上達の道だったりします。&lt;br />
&lt;br />
　次回はプログラムを書く上でとても重要な（ある意味一番重要で一番大変かもしれない）デバッグについて簡単に説明します。</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise11.html">
        <title>練習問題11</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise11.html</link>
        <description>　とりあえず最低限必要そうな機能は一通り揃ったようなので、最後に仕上げとしてアイコンを付け加えてみましょう。&lt;br />
　まず最初にアイコンの準備をします。アプリケーションやファイルのアイコンは「.icns」という拡張子のファイル形式で準備します。ファイルを作るにはまず元になる画像を一般的な画像フォーマット（jpegやpng、tiffなど）で準備します。次にDeveloper Toolsのアプリケーションフォルダに入っている「Icon Composer」というアプリ（/Developer/Applications/Utilities/Icon Composer.app）を起動し、各四角</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-10-19T13:41+09:00</dc:date>
        <content:encoded>　とりあえず最低限必要そうな機能は一通り揃ったようなので、最後に仕上げとしてアイコンを付け加えてみましょう。&lt;br />
　まず最初にアイコンの準備をします。アプリケーションやファイルのアイコンは「.icns」という拡張子のファイル形式で準備します。ファイルを作るにはまず元になる画像を一般的な画像フォーマット（jpegやpng、tiffなど）で準備します。次にDeveloper Toolsのアプリケーションフォルダに入っている「Icon Composer」というアプリ（/Developer/Applications/Utilities/Icon Composer.app）を起動し、各四角に準備したイメージファイルをドラッグして保存すれば完成です。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise11_1.png">&lt;/div />&lt;br />
&lt;br />
　サンプルとして&lt;a href="http://wakabamac.blog95.fc2.com/">Wakaba&lt;/a>さん制作のCalcBMI用アイコンのファイルを置いておきますので、&lt;a href="http://samples/Exercise11_icon1.zip">ダウンロード&lt;/a>してアイコンを作ってみてください。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise11_0.png">&lt;/div />&lt;br />
&lt;br />
&lt;br />
　次にアイコンをXcodeのプロジェクトに登録して、アプリケーションのアイコンとして認識されるように設定します。まずは作ったicnsファイルをプロジェクトフォルダの適当な所に移動してください。移動したらCalcBmiプロジェクトファイルを開き、icnsファイルを「グループとファイル」の「Resources」の下にドラッグして追加します。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise11_2.png">&lt;/div />&lt;br />
&lt;br />
　追加したら「ターゲット」の下の「CalcBmi」を選択し、「ファイル」メニューの「情報を見る」を選択して、アプリケーションの設定ウィンドウを開きます。ウィンドウ内の「プロパティ」タブを選択し、「アイコンファイル」の欄にアイコンのファイル名を入力するか、先ほどドラッグして追加したicnsファイルを欄の中にドラッグして、ファイル名を入力します。これで設定完了です。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise11_3.png">&lt;/div />&lt;br />
&lt;br />
　あとはいつものようにアプリケーションをビルドすることでアイコンがちゃんとついた立派なアプリケーションが完成します。&lt;br />
&lt;br />
&lt;br />
　これだけではつまらないので、今回はもう一工夫してみます。アプリケーションの状態にあわせてDockのアイコンを変更します。まずは画像を準備します。今回はわざわざicnsファイルを作らないで普通のpngファイルなどを準備するだけで大丈夫です。&lt;a href="http://samples/Exercise11_icon2.zip">こちら&lt;/a>にサンプルを置いておきます。アプリケーションアイコンと同じく&lt;a href="http://wakabamac.blog95.fc2.com/">Wakaba&lt;/a>さん制作です。&lt;br />
　ファイルを準備したらアプリケーションアイコンと同様にドラッグアンドドロップでXcodeプロジェクトウィンドウのResourcesの下に追加します。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise11_4.png">&lt;/div />&lt;br />
&lt;br />
　次にプロジェクトに追加したイメージファイルのデータを、プログラム中で取り出してDockに表示する手順です。まずはイメージの取り出し方です。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">  NSImage	*anIcon;
  anIcon=[NSImage imageNamed:@"blue.icns"];&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　画像を取り扱うにはその名の通りNSImageというクラスを使います。そしてプロジェクトに追加してあるイメージファイルを取得するには「+ (id)imageNamed:(NSString *)name」というNSImageクラスのクラスメソッドを利用します。引き数「name」に読み込みたいイメージファイルの名前をNSStringで渡してやれば、アプリケーションバンドルの中から該当するファイルを探して読み込み、NSImageオブジェクトとして返してくれます。簡単ですね。&lt;br />
　次にNSImageをDockに表示する方法です。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">  [NSApp setApplicationIconImage:anIcon]; &lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　たった一行です。最初の「NSApp」はアプリケーション本体を司るオブジェクトで「NSApplication」クラスのインスタンスです。一見クラスメソッドのようにも見えますが、クラス名ではありません。グローバル変数といって、プログラム中どこからでも呼び出すことができる特殊な変数です。例えば&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">  [NSApp terminate:nil]; &lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　と書くとプログラムからアプリケーションを終了させることができます。このNSAppの「setApplicationIconImage:anIcon:」メソッドに、Dockに表示させたい画像のNSImageインスタンスを渡せばDockの内容が変わります。&lt;br />
&lt;br />
&lt;br />
　ということでここで問題です。BMI計算の結果にあわせて、痩せ過ぎなら青、太り気味なら黄色、肥満なら赤とDockのアイコン表示が変わるように変更してみてください。&lt;br />
&lt;br />
&lt;br />
&lt;div align="right">解答は&lt;a href="http://answer11.html">こちら&lt;/a>　　　&lt;/div />&lt;br />
</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer10.html">
        <title>練習問題10</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer10.html</link>
        <description>　解答編です。まずはコードの追加部分。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (void)setValues
{
  [bmiField setFloatValue:bmi];
  [bmiSlider setFloatValue:bmi];
  
  [heightField setFloatValue:height];
  [heightSlider setFloatValue:height];
  
  [weightField setFloatValue:weight];
  [weightSlide</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-09-05T18:19+09:00</dc:date>
        <content:encoded>　解答編です。まずはコードの追加部分。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (void)setValues
{
  [bmiField setFloatValue:bmi];
  [bmiSlider setFloatValue:bmi];
  
  [heightField setFloatValue:height];
  [heightSlider setFloatValue:height];
  
  [weightField setFloatValue:weight];
  [weightSlider setFloatValue:weight];
  
  if(bmi&lt;18)
    [alertField setStringValue:NSLocalizedString(@"too thin",@"")];
  else if(bmi />25)
    [alertField setStringValue:NSLocalizedString(@"too fat",@"")];
  else
    [alertField setStringValue:@""];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　BMIを計算した後、結果に応じてalertFieldにローカライズされた文字列をセットしています。メッセージのサンプルはこちら。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">"too thin" = "もっと飯食え！";
"too fat" = "もっと運動しろ！";&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　まあこの文言は何でも構いません。&lt;br />
　それからもちろんこのalertFieldをウィンドウに追加してやる必要があります。これは今更説明する必要はありませんね。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise10_4.png">&lt;/div />&lt;br />
&lt;br />
　システム環境設定の「言語環境」の「言語」タブでEnglishを日本語の上にドラッグすることでCalcBmiを英語版で起動させることができます。正しくローカライズできているかどうか試してみてください。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise10_5.png">&lt;/div />&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise10_6.png">&lt;/div />&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise10_7.png">　&lt;img src="images/exercise10_8.png">&lt;/div />&lt;br />
&lt;br />
　サンプルを&lt;a href="http://samples/Exercise10.zip">こちら&lt;/a>に置いておきます。&lt;br />
&lt;br />
　ローカライズはこのようにものすごく簡単にできるのですが、バージョンアップのたびに同じような作業が必要になるので、後々結構面倒くさくなってきます。世の中にはローカライズを支援するためのソフトがいくつもありますので、自作のソフトを公開するようになったら、そのようなソフトを試してみると良いでしょう。その際は拙作&lt;a href="http://homepage.mac.com/nsekine/SYW/SYWSoft/softOSX.html#iLingual">iLingual&lt;/a>もお試しください。&lt;br />
</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise10.html">
        <title>練習問題10</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise10.html</link>
        <description>　今回はローカライズについて説明します。ローカライズというのは英語のソフトを日本語にしたり、日本語のソフトを英語にしたりする作業のことです。今までは日本語のみでCalcBmiを作ってきましたが、体重の問題は世界共通（日本よりむしろ海外の方が大きな問題かも）、とりあえず英語にするだけで今までよりずっと多くの人に使ってもらうことができます。&lt;br />
　ローカライズの方法はとても簡単です。ウィンドウなどのインターフェイスを作成するnibファイルはデフォルトでは「English.lproj」というフォルダに入っています。このフォルダを丸ごと複製し、複製したフォルダに「Japanese.lpr</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-09-05T18:02+09:00</dc:date>
        <content:encoded>　今回はローカライズについて説明します。ローカライズというのは英語のソフトを日本語にしたり、日本語のソフトを英語にしたりする作業のことです。今までは日本語のみでCalcBmiを作ってきましたが、体重の問題は世界共通（日本よりむしろ海外の方が大きな問題かも）、とりあえず英語にするだけで今までよりずっと多くの人に使ってもらうことができます。&lt;br />
　ローカライズの方法はとても簡単です。ウィンドウなどのインターフェイスを作成するnibファイルはデフォルトでは「English.lproj」というフォルダに入っています。このフォルダを丸ごと複製し、複製したフォルダに「Japanese.lproj」という名前を付けます。&lt;br />
　&lt;br />
&lt;div align="center">&lt;img src="images/exercise10_1.png">&lt;/div />&lt;br />
&lt;br />
　次に「Japanese.lproj」フォルダの中のファイルをXcodeのウィンドウにドラッグして登録します。「MainMenu~.nib」というファイル（拡張子の前に「~」がついているファイル）は「MainMenu.nib」のバックアップファイルで、登録したり編集する必要はありません。&lt;br />
&lt;br />
&lt;div align="center">&lt;img src="images/exercise10_2.png">　→　&lt;img src="images/exercise10_3.png">&lt;/div />&lt;br />
&lt;br />
　後はEnglishのnibファイルを英語に、Japaneseのファイルを日本語にしてやればOKです。メニューの名前の付け方などはApple純正のアプリケーションを参考にしてください。&lt;br />
&lt;br />
　これだけでは物足りないのでもう一つ、「Localizable.strings」というファイルを追加します。これはプログラム中で使うメッセージなどをローカライズするためのソフトです。例えばBMIが18よりも低い時ウィンドウ上に「痩せ過ぎだよ」というメッセージを入れる場合どうすれば良いでしょうか。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">[textField setStringValue:@"痩せ過ぎだよ"];&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　と書いてしまうと、英語版でも日本語のメッセージが表示されてしまいます（それ以前にプログラムに日本語を直接書込んでも、文字化けしてしまって正しく表示されませんが）。そのためにこのようなプログラム中で使うメッセージの類いはすべて「Localizable.strings」という別ファイルに分けておく必要があります。ファイルのサンプルを&lt;a href="http://samples/Localizable.zip">こちら&lt;/a>からダウンロードしてください。&lt;br />
　ファイルの中身はUTF-8形式のただのテキストファイルで、「"○○" = "××";」という形式になっています。左側がキーワードで右側がローカライズされたメッセージ、例えば「"River" = "河";」という感じになります。これをプログラム中で使うには「NSLocalizedString()」という関数を使います。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">NSString  *aRiver=NSLocalizedString(@"River",@"");&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　関数の最初の引き数は「Localizable.strings」のキー名、二番目の引き数はコメントです。コメントは何を書いても関数の結果には影響ありません。単なるメモです。&lt;br />
　これでシステムの言語の優先順位に従って適切な文字を取り出すことができます。&lt;br />
&lt;br />
　というところで説明はおしまい。で、問題です。
&lt;ol type="1">
&lt;li />CalcBmiをローカライズして、英語と日本語のインターフェイスを付け加えてください。&lt;/li />
&lt;li />BMIが18より小さいとき、25よりも大きいとき、警告のメッセージをウィンドウ上に表示してください。&lt;/li />
&lt;/ol />　&lt;br />
&lt;br />
&lt;br />
&lt;div align="right">解答は&lt;a href="http://answer10.html">こちら&lt;/a>　　　&lt;/div />&lt;br />
</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer9.html">
        <title>練習問題9</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer9.html</link>
        <description>　解答例です。初期設定への読み書きそのものは解説の部分でほとんど例示してしまったので、特に問題は無いと思います。問題はどこでその処理を行うか、です。解答サンプルは&lt;a href="http://samples/Exercise9.zip">こちら&lt;/a>。&lt;br />
&lt;br />
　まずは初期設定データの読み書きを行う部分を紹介します。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//初期設定の読み込み
- (void)loadUserDefaults
{
  NSUserDefaults  *aDefault=</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-09-05T12:44+09:00</dc:date>
        <content:encoded>　解答例です。初期設定への読み書きそのものは解説の部分でほとんど例示してしまったので、特に問題は無いと思います。問題はどこでその処理を行うか、です。解答サンプルは&lt;a href="http://samples/Exercise9.zip">こちら&lt;/a>。&lt;br />
&lt;br />
　まずは初期設定データの読み書きを行う部分を紹介します。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//初期設定の読み込み
- (void)loadUserDefaults
{
  NSUserDefaults  *aDefault=[NSUserDefaults standardUserDefaults];
  if([aDefault floatForKey:@"height"])
    height=[aDefault floatForKey:@"height"];
  else
    height=[heightField floatValue];
    
  if([aDefault floatForKey:@"weight"])
    weight=[aDefault floatForKey:@"weight"];
  else
    weight=[weightField floatValue];
}

//初期設定の保存
- (void)saveUserDefaults
{
  NSUserDefaults  *aDefault=[NSUserDefaults standardUserDefaults];
  [aDefault setFloat:height forKey:@"height"];
  [aDefault setFloat:weight forKey:@"weight"];
  [aDefault synchronize];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　例と違うのは読み込みの部分でifを使って分岐している点です。これは初めての起動のときは身長体重が0にセットされてしまうのを防ぐ目的でこうしてあります。もう少し短く書くこともできますが、コードが読みにくくなるので若干冗長な書き方をしてあります。&lt;br />
&lt;br />
　で問題はこの二つのメソッドをどこで呼ぶかです。読み込みのメソッドは考えるまでもなく「awakeFromNib」で呼べばOKですね。では保存はどこで行えば良いでしょうか？もちろん「アプリケーションが終了する前」ですが、これはどのように実装すれば良いのでしょうか？&lt;br />
　実はこれについては&lt;a href="http://answer6.html">練習問題6&lt;/a>の解答で既に説明してあります。読み直してみてください。&lt;br />
&lt;br />
　・・・NSAppの「NSApplicationWillTerminateNotification」ノーティフィケーションをつかまえてやれば良いのです。ということでこんな感じ。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (void)awakeFromNib
{
  NSNotificationCenter  *aCenter=[NSNotificationCenter defaultCenter];
  [aCenter addObserver:NSApp
      selector:@selector(terminate:)
      name:@"NSWindowWillCloseNotification"
      object:bmiWindow];
  [aCenter addObserver:self
      selector:@selector(applicationWillTerminate:)
      name:@"NSApplicationWillTerminateNotification"
      object:NSApp];

  //初期設定の保存
  [self loadUserDefaults];

  //BMIを計算して結果をすべてのコントロールにセット
  [self calcBMIAndSet];
}

- (void)applicationWillTerminate:(NSNotification *)pNotification
{
  //初期設定の保存
  [self saveUserDefaults];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　ノーティフィケーションについては&lt;a href="http://answer6.html">練習問題6&lt;/a>を読みかえしてみてください。&lt;br />
&lt;br />
　これで起動するたびに前回に設定した身長と体重が表示されるようになります。試してみてください。&lt;br />
&lt;br />
　そうそう、最後に一つ、初期設定を扱う上で大事なことを追記しておきます。初期設定ファイルの名前はアプリケーションのプロパティの「識別子」の設定に依存します。プロジェクトウィンドウの「ターゲット」の下のアプリケーション名を選択してCommand+iで情報ウィンドウが開きますので、プロパティタブで編集することができます。&lt;br />
　&lt;br />
&lt;div align="center">&lt;img src="images/exercise9_1.png">&lt;/div />&lt;br />
&lt;br />
　ここでは識別子を「learnCocoa.sekn.CalcBmi」にしてありますので、初期設定ファイルは「learnCocoa.sekn.CalcBmi.plist」という名前で表示されます。この識別子に特別なルールは内容ですが一般的には「com.会社名.プロダクト名」という感じで設定しているようです。独自のドメインを持っている場合はその逆をセットすれば良いでしょう（例えば「hogehoge.net」さんであれば「net.hogehoge.appname」という感じ）。一度セットすると後で変えるのは大変なので、公開する前によく考えましょう。</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise9.html">
        <title>練習問題9</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/exercise9.html</link>
        <description>　今回はデータを初期設定ファイルに保存する方法について紹介します。初期設定にデータを出し入れするには「NSUserDefaults」というクラスを使います。このクラスのリファレンスは&lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html">こちら&lt;/a>。まずは「Overview」の所を読んでみてください。&lt;br />
&lt;br />
&lt;br />
&lt;br </description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-09-05T12:48+09:00</dc:date>
        <content:encoded>　今回はデータを初期設定ファイルに保存する方法について紹介します。初期設定にデータを出し入れするには「NSUserDefaults」というクラスを使います。このクラスのリファレンスは&lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html">こちら&lt;/a>。まずは「Overview」の所を読んでみてください。&lt;br />
&lt;br />
&lt;br />
&lt;br />
&lt;br />
　本来ならばこれを読み、あとは&lt;a href="http://www.google.co.jp/search?ie=utf-8&amp;oe=utf-8&amp;q=NSUserDefaults">Googleで検索&lt;/a>するなどして使い方を自分で調べなくてはいけないのですが、まだそれは難しいと思いますので、簡単に使い方を説明します。NSUserDefaultの使い方は簡単に分けて三段階あります。
&lt;ol type="1">
&lt;li />NSUserDefaultインスタンスの取り出し&lt;/li />
&lt;li />NSUserDefaultインスタンスから必要なデータを取り出し、もしくは必要なデータを格納&lt;/li />
&lt;li />NSUserDefaultインスタンスを保存&lt;/li />
&lt;/ol />
&lt;br />
　具体的にはこんな感じ。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//データの取り出し
-(void)loadPreference
{
  NSUserDefaults  *aDefault=[NSUserDefaults standardUserDefaults];
  height=[aDefault floatForKey:@"height"];
  weight=[aDefault floatForKey:@"weight"];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//データの保存
-(void)loadPreference
{
  NSUserDefaults  *aDefault=[NSUserDefaults standardUserDefaults];
  [aDefault setFloat:height forKey:@"height"];
  [aDefault setFloat:weight forKey:@"weight"];
  [aDefault synchronize];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　まず最初の&lt;br />
[NSUserDefaults standardUserDefaults]&lt;br />
　で、デフォルトのNSUserDefaultsオブジェクトを取り出します。つまりユーザディレクトリの「/Library/Preferences」以下にある適当な初期設定ファイルの中身が読み込まれます。「デフォルトの」ということで必要に応じていろいろな初期設定ファイルのデータを読み書きできるのですが、とりあえずは「standardUserDefaults」だけ覚えておけばOKです。そしてその次の二行でデータの取り出し、セットをしています。&lt;br />
　NSUserDefaultsにデータをセットするときは「キー」を付けてデータをセットします。キーというのはデータのラベルのようなもので、この例の場合「身長」のデータに「height」というキーを付けてセットしています。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//データのセット
  [aDefault setFloat:height forKey:@"height"];
&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　すると次回身長のデータを取り出したいときは「height」のキーがくっついたデータとして取り出すことができるわけです。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//データの取り出し
  height=[aDefault floatForKey:@"height"];
&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　この例ではfloatのデータを読み書きしていますが、その他にint用、bool用、object用のメソッドが用意されています。&lt;br />
&lt;br />
　そしてセットしたデータを初期設定ファイルに書込んで保存するときは「synchronize」メソッドを呼んでやります。&lt;br />
&lt;pre />&lt;code />&lt;div id="source">//データをファイルに書込み
  [aDefault synchronize];
&lt;/div />&lt;/code />&lt;/pre />&lt;br />
　このメソッドを実行することでセットしたデータが初めてファイルに書込まれます。いくらsetFloat:forKey:などでデータをセットしても、これを忘れると保存されないので注意しましょう。またデータを読込むだけならばsynchronizeを呼ぶ必要はありません。&lt;br />
&lt;br />
&lt;br />
　ということでここで問題です。身長と体重を初期設定に保存して、次回起動時に反映されるようにCalcbmiを改造してみてください。&lt;br />
&lt;br />
&lt;br />
&lt;br />
&lt;div align="right">解答は&lt;a href="http://answer9.html">こちら&lt;/a>　　　&lt;/div />&lt;br />
</content:encoded>
    </item>
    <item rdf:about="http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer8.html">
        <title>練習問題8</title>
        <link>http://homepage.mac.com/nsekine/SYW/SYWSoft/learnCocoa/answer8.html</link>
        <description>　では解答例です。ソースコードを自由に書けるようになってきて、課題に対する解答も千差万別、いろいろな書き方が出てくると思います。あくまでも私の例ですので、それぞれ好きなやり方を見つけてください。&lt;br />
　以下変更に関係のある部分だけ。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (IBAction)changeBMI:(id)sender
{
  bmi=[sender floatValue];
  [self calcWeightAndSet];
}
- (IBAction)changeHeight:</description>
        <dc:creator>sekn</dc:creator>
        <dc:date>2007-07-13T23:03+09:00</dc:date>
        <content:encoded>　では解答例です。ソースコードを自由に書けるようになってきて、課題に対する解答も千差万別、いろいろな書き方が出てくると思います。あくまでも私の例ですので、それぞれ好きなやり方を見つけてください。&lt;br />
　以下変更に関係のある部分だけ。&lt;br />
&lt;br />
&lt;pre />&lt;code />&lt;div id="source">- (IBAction)changeBMI:(id)sender
{
  bmi=[sender floatValue];
  [self calcWeightAndSet];
}
- (IBAction)changeHeight:(id)sender
{
  height=[sender floatValue];
  [self calcBMIAndSet];
}
- (IBAction)changeWeight:(id)sender
{
  weight=[sender floatValue];
  [self calcBMIAndSet];
}

- (void)calcWeightAndSet
{
  weight=calculateWeight(height, bmi);  
  [self setValues];
}
- (void)calcBMIAndSet
{
  bmi=calculateBMI(height, weight);  
  [self setValues];
}

- (void)setValues
{
  [bmiField setFloatValue:bmi];
  [bmiSlider setFloatValue:bmi];
  
  [heightField setFloatValue:height];
  [heightSlider setFloatValue:height];
  
  [weightField setFloatValue:weight];
  [weightSlider setFloatValue:weight];
}&lt;/div />&lt;/code />&lt;/pre />&lt;br />
&lt;br />
　ソースコードを読めばわかると思うので、説明は省略します。手抜きじゃないですよ(笑)。当然Nibファイルやヘッダファイルも直す必要があります。&lt;br />
　実はこれだけで動かすと、起動直後の挙動が少し変になります。なぜかというと・・・自分で調べてなおしてみてください。宿題ということで。それを含めた解答サンプルは&lt;a href="http://samples/Exercise8.zip">こちら&lt;/a>。修正部分に理由を書いておきました。&lt;br />
&lt;br />
　今回は割と簡単だったと思いますが、いかがでしょうか？次回はちょっと欲張ってキーバリューコーディングについての説明か、もしくは初期設定への保存方法について解説したいと思います。初期設定の方が先かな？&lt;br />
&lt;br />
</content:encoded>
    </item>
</rdf:RDF>