<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
	<channel>
		<title>みるくCocoa</title>
		<link>http://www.stripe-net.jp/cocoa/</link>
		<description>MacOSXでCocoaアプリケーションを作ろう♪</description>
		<language>ja</language>
		<pubDate>Tue, 15 May 2012 20:37:32 +0900</pubDate>
		<lastBuildDate>Tue, 15 May 2012 20:37:32 +0900</lastBuildDate>
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
		<generator>Milk Cocoa Blog System</generator>
		<managingEditor>simamura@coral.ocn.ne.jp</managingEditor>
		<webMaster>simamura@coral.ocn.ne.jp</webMaster>
		
		<item>
			<title>OSAtomicFifoQueueを使った非同期スレッド間通信</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20120515.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;&lt;code&gt;OSAtomicFifoQueue&lt;/code&gt;を使って、非同期スレッド間通信を行う&lt;a href=&quot;http://www.stripe-net.jp/cocoa/downloads/echothread.zip&quot;&gt;サンプルコード&lt;/a&gt;を作ってみた。&lt;br/&gt;&lt;br/&gt;Cocoaでマルチスレッドなプログラムを作るとき、大抵の場合は&lt;code&gt;NSOperation&lt;/code&gt;やGCDを使えば済むかもしれません。しかし、ときには手動でスレッドを作って、スレッド間通信をしたくなることもあります。&lt;br/&gt;&lt;br/&gt;例えば、複数のスレッドで一つのデータを共有する場合、真っ先に思いつくのは&lt;code&gt;NSLock&lt;/code&gt;などを使ってスレッドセーフにすることです。しかしこの方法は手軽で確実な反面、パフォーマンス面に問題があります。それは、&lt;code&gt;NSLock&lt;/code&gt;が基本的にスレッドを「一時停止」させるための機能だからです。そもそも、なぜマルチスレッドにしたのかという理由にもよりますが、せっかくマルチスレッドで動いているのに、スレッドを止めてしまうことはあまり好ましい状況ではありません。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/2012/blog20120515-1.png&quot; width=&quot;480&quot; height=&quot;240&quot;/&gt;&lt;br/&gt;&lt;br/&gt;このようなときは、共有したいデータの管理を一つのスレッドに全て任せてしまい、複数のスレッドで一つのスレッドを共有するという方法を取ります。各スレッドからLockを使わずに、その一つのスレッドに対してメッセージを送れれば、データ編集が完了するまでの間、各スレッドは一時停止せずに済みます。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/2012/blog20120515-2.png&quot; width=&quot;480&quot; height=&quot;240&quot;/&gt;&lt;br/&gt;&lt;br/&gt;そしてこのとき、Lockせずにメッセージを送るために使うのが&lt;code&gt;OSAtomicFifoQueue&lt;/code&gt;です。&lt;br/&gt;以前はCarbonライクな&lt;code&gt;MPQueue&lt;/code&gt;というのがありましたが、MacOSX10.7になって&lt;code&gt;OSAtomicFifoQueue&lt;/code&gt;に置き替えられました。&lt;code&gt;OSAtomicFifoQueue&lt;/code&gt;を使うには、&lt;code&gt;libkern/OSAtomic.h&lt;/code&gt;をインポートします。&lt;br/&gt;&lt;br/&gt;&lt;code&gt;OSAtomicFifoQueue&lt;/code&gt;はLinked-Listなデータ構造を持つキューで、以下のような形になります。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/2012/blog20120515-3.png&quot; width=&quot;480&quot; height=&quot;200&quot;/&gt;&lt;br/&gt;ヘッダーにはキュー全体を統括する&lt;code&gt;OSFifoQueueHead&lt;/code&gt;という構造体が定義されていますが、&lt;code&gt;Item&lt;/code&gt;に相当するデータ構造は定義されていません。&lt;br/&gt;これは、Linked-Listな要素なので、次の要素へのリンクポインタさえ用意すれば、どんな構造体でもOKと言う事で、ユーザー側で自由に定義できるようになっているからです。&lt;br/&gt;&lt;br/&gt;キューにItemを出し入れする、&lt;code&gt;OSAtomicFifoDequeue()&lt;/code&gt;や&lt;code&gt; OSAtomicFifoEnqueue()&lt;/code&gt;と言った関数には、&lt;code&gt;offset&lt;/code&gt;という引数があり、これでユーザー定義された構造体の中でのリンクポインタの位置を指定します。&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;//&lt;br/&gt;// ユーザー定義のItemクラス&lt;br/&gt;//&lt;br/&gt;@interface Item : NSObject&lt;br/&gt;{&lt;br/&gt;    NSString* title;&lt;br/&gt;    NSURL* url;&lt;br/&gt;&lt;br/&gt;    void* link; // リンクポインタ&lt;br/&gt;}&lt;br/&gt;@property(strong) NSString* title;&lt;br/&gt;@property(strong) NSURL* url;&lt;br/&gt;@end&lt;br/&gt;&lt;br/&gt;//&lt;br/&gt;// キューの初期化&lt;br/&gt;//&lt;br/&gt;OSFifoQueueHead queue;&lt;br/&gt;queue.opaque1 = NULL;&lt;br/&gt;queue.opaque2 = NULL;&lt;br/&gt;queue.opaque3 = 0;&lt;br/&gt;&lt;br/&gt;//&lt;br/&gt;// キューへの挿入&lt;br/&gt;//&lt;br/&gt;Item* item = [Item new];&lt;br/&gt;item.title = @&quot;Hello&quot;;&lt;br/&gt;item.url = [NSURL URLWithString:@&quot;http://hello.jp&quot;];&lt;br/&gt;&lt;br/&gt;Ivar ivar = class_getInstanceVariable([Item class], &quot;link&quot;);&lt;br/&gt;size_t offset = ivar_getOffset(ivar);&lt;br/&gt;&lt;br/&gt;OSAtomicFifoEnqueue(&amp;queue, item, offset);&lt;br/&gt;&lt;br/&gt;//&lt;br/&gt;// キューから取り出し&lt;br/&gt;//&lt;br/&gt;Item* item = OSAtomicFifoDequeue(&amp;queue, offset);&lt;br/&gt;&lt;br/&gt;if (item) {&lt;br/&gt;    NSLog(@&quot;%@ %@&quot;, item.title, item.url);&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;キューが空の場合、&lt;code&gt;OSAtomicFifoDequeue()&lt;/code&gt;関数はすぐに&lt;code&gt;NULL&lt;/code&gt;を返し、決してキューに新たなItemが挿入されるまでスレッドを停止させたりはしません。そのため、Itemの挿入を待ち受けるには、&lt;code&gt;CFRunLoop&lt;/code&gt;のカスタムSourceを利用します。&lt;br/&gt;&lt;br/&gt;今回のサンプルコードの内容は、「割り算スレッド」です。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/2012/blog20120515-4.png&quot; width=&quot;480&quot; height=&quot;240&quot;/&gt;&lt;br/&gt;MainスレッドからWorkerスレッドへ、「12 / 4」のような文字列を送信すると、「12 / 4 = 3」という文字列が返ってきます。MainスレッドもWorkerスレッドもRunLoopを使用しており、それぞれ非同期で動きます。そのため、タイミングによっては文字列を送信してもすぐに受信できないかもしれません。&lt;br/&gt;ゼロ除算を行おうとすると例外が発生して、Workerスレッドが落ちるようにしています。落ちたWorkerスレッドはMainスレッドによって、すぐに再起動させられます。&lt;br/&gt;Workerスレッドでエラー等が発生したとき、エラーからの回復を試みてもいいですが、一度スレッドを落としてから再起動させるのも一つの方法です。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Tue, 15 May 2012 20:37:32 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20120515.html</guid>
		</item>
		
		<item>
			<title>もう少しでiDiskが終わります</title>
			<link>http://www.stripe-net.jp/cocoa/admin/blog20120504.html</link>
			<category>サーバー運営</category>
			<description>&lt;p&gt;来月でiDiskがサービス終了となります。&lt;br/&gt;iDiskは、このサイトのバックアップだけでなく、画像ファイルやダウンロードファイルなどの置き場所にもなっていました。&lt;br/&gt;&lt;br/&gt;かつては、サーバーの回線速度が1.5Mbpsと遅かったので、負荷分散のため比較的容量の大きなファイルを別サーバー（つまりiDisk）に置いていました。&lt;br/&gt;でも、このたびiDiskがサービス終了ということで、iDiskに置いていたのものリンク先を修正して全て自分のサーバーに移動させました。&lt;br/&gt;&lt;br/&gt;サーバーの負荷分散は、当初は良い考えだと思っていましたが、こんなふうにレンタルサーバーのサービスが終了したりすると結構大変なことになりますね。&lt;/p&gt;</description>
			<pubDate>Fri, 04 May 2012 22:08:34 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/admin/blog20120504.html</guid>
		</item>
		
		<item>
			<title>MIDIWindシーケンサーの開発状況</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20120325.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;昨年の４月から開発を続けているMIDIWindシーケンサーの開発状況はこんな感じです。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/2012/blog20120325.jpg&quot; width=&quot;480&quot; height=&quot;360&quot;/&gt;&lt;br/&gt;ある程度編集が可能になっていますが、のんびりと開発してるので、完成度は50%ぐらいでしょうかね。&lt;br/&gt;来年ぐらいには、初期リリースしたいな。&lt;/p&gt;</description>
			<pubDate>Sun, 25 Mar 2012 13:55:51 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20120325.html</guid>
		</item>
		
		<item>
			<title>副作用とは？</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20111217.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;関数型言語でよく話に出てくる「副作用」。今回は、その副作用についてまとめてみる。&lt;br/&gt;&lt;br/&gt;まず、副作用とは「別の世界に与える影響」または「別の世界から受ける影響」のことです。&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;int function(int a, int b);&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;例えば、C言語で上記のように定義された関数について、同じ値の引数なら戻り値も必ず同じになるとき、この関数には副作用がありません。おそらく、２つの引数からなんらかの演算によって戻り値を算出する内容のコードになっているのでしょう。&lt;br/&gt;&lt;/p&gt;&lt;pre&gt;void action(int a, int b);&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;しかし、上記のように戻り値が無い関数の場合、引数として入力された値はどこへ行ってしまったのでしょうか。この関数は何もしない関数なのでしょうか。もし何か処理を行っているとすれば、その結果はどこに出力されたのでしょうか。&lt;br/&gt;これが、副作用を持つ関数です。この関数の処理結果は「別の世界」へと送られたのです。&lt;br/&gt;&lt;br/&gt;「別の世界」をもう少し具体的に言うと、「自分と平行して動作しているもの」となります。&lt;br/&gt;&lt;br/&gt;コンピュータでは、CPU、GPU、USBコントローラ、IDEコントローラ、Audioデバイスなどが、全て同時平行的に動作しています。CPU動作中はGPUが停止してて画面が表示されない、などということはありません。&lt;br/&gt;つまり、全てのI/Oデバイスへのアクセスは副作用なのです。&lt;br/&gt;&lt;br/&gt;また、１台のコンピュータにCPUが２つあった場合、２つのCPUは平行して動作します。そして、OSのカーネルが提供するマルチプロセスやマルチスレッドなどは、仮想的なCPUを作り出すサービスです。&lt;br/&gt;つまり、プロセス間通信やスレッド間通信も副作用です。&lt;br/&gt;&lt;br/&gt;さらに、下記のようなコードを書いた場合、&lt;/p&gt;&lt;pre&gt;int a = 3;&lt;br/&gt;int b = 4;&lt;br/&gt;a = a + b + 5;&lt;/pre&gt;&lt;p&gt;変数aは、再代入によって内容を書き替えています。これは、メインメモリをデータストレージデバイスのように扱っていることになるため、これもI/Oデバイスへのアクセスと同様に副作用です。ちなみに、変数bは再代入を行っておらず、実質的に定数であると考えられるため、これは副作用にはなりません。&lt;br/&gt;&lt;br/&gt;副作用の伴うコードは、可能な限り排除しなければなりません。なぜなら、副作用はバグの発生と大きな関係があるからです。&lt;br/&gt;例えば、I/Oデバイスへの書き込みは失敗するかもしれません。また、I/Oデバイスからはどんな値が読み込まれるか完全に予測することはできません。プログラムを組む際は、これら予想外の事態に配慮しなければなりません。もし、予想外の事態に対処できなければ、これがバグという形になって表れるからです。&lt;br/&gt;&lt;br/&gt;この予想外への対応は、副作用を含むコードと共に行われます。そして、「予想外」に対応するコードは、大抵は面倒で書くのに時間の掛かるコードです。副作用があまりにも多いコードだと、この予想外への対応が困難になります。面倒だからといってここでコードを省略すると、それがバグに繋がってしまいます。&lt;br/&gt;&lt;br/&gt;関数型言語では副作用を特別扱いするものが多く、副作用への対処がやりやすくなっています。逆に、手続き型言語では、副作用の存在自体が見えにくく対処しづらくなっています。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Sat, 17 Dec 2011 23:34:56 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20111217.html</guid>
		</item>
		
		<item>
			<title>破損した書類でもエラーにしない</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20111113.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;あるアプリケーションで書類を開こうとしてファイルを読み込んだとき、もしそのファイルのデータが破損していた場合どうしたら良いでしょうか？&lt;br/&gt;&lt;br/&gt;これまでは、「この書類は破損しています」とアラートパネルを表示し、書類を開く処理は失敗に終わらせる。というのが、ほとんど常識でした。そのファイルは、おそらくアプリケーションのバグなどによって、壊れた状態で最後に保存されてしまったのです。運良くバックアップでもないかぎり、もう諦めるしかありません。&lt;br/&gt;&lt;br/&gt;ところが、MacOSX10.7の「バージョン管理」機能によって、この状況は変わります。&lt;br/&gt;「運良く」ではなく、ごく日常的に書類のバックアップを取るような形になるからです。&lt;br/&gt;しかし、Cocoaのデフォルトの実装では、書類を開かないと、その書類の過去バージョンにアクセスできません。バージョン管理は、書類の変更履歴を残すもので、破損したファイルを復旧させることは想定されていないのです。&lt;br/&gt;&lt;br/&gt;でも、破損したファイルでもエラーにせず、とりあえず開けるようになっていれば、破損したファイルを救うことも可能になります。MacOSX10.7用のアプリケーションを開発する際は、このような配慮も必要になってくるのかもしれませんね。&lt;/p&gt;</description>
			<pubDate>Sun, 13 Nov 2011 02:01:04 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20111113.html</guid>
		</item>
		
		<item>
			<title>iCloud Storageのサンプルコード</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20111029.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;iCloud Storageの動作を確認するべく、&lt;a href=&quot;http://www.stripe-net.jp/cocoa/downloads/lion_sample2.zip&quot;&gt;サンプルコード&lt;/a&gt;を作って見ました。&lt;br/&gt;&lt;br/&gt;iCloud Storageを利用するには、まずそのアプリケーションを登録しなければなりません。iCloud Storage内には、アプリケーションごとに別々に領域が確保されます。&lt;br/&gt;登録するには、Mac Developer Programの会員になり、メンバーセンターで登録手続きを行う必要があります。&lt;br/&gt;1. アプリケーションIDの登録&lt;br/&gt;2. 開発者としての証明書の登録&lt;br/&gt;3. 開発モードなら、開発機の登録&lt;br/&gt;4. 規定書の作成とダウンロード&lt;br/&gt;ダウンロードした規定書は、システム環境設定のプロファイルとXcodeオーガナイザーのDevicesにインストールします。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20111029-1.png&quot;/&gt;&lt;br/&gt;&lt;br/&gt;Xcodeでプロジェクトを作成したら、規定書に基づいてセットアップします。&lt;br/&gt;1. Summaryで、Identifierに登録したアプリケーションIDを設定&lt;br/&gt;2. Summaryで、Code Sign Applicationにチェック&lt;br/&gt;3. Summaryで、Enable Entitlementsにチェック&lt;br/&gt;4. Summaryで、Entitlements Fileを設定&lt;br/&gt;5. Summaryで、iCloud ContainersにアプリケーションIDを設定&lt;br/&gt;6. Build Settingsで、規定書に対応したCode Signing Identityを設定&lt;br/&gt;これでやっと準備完了です。&lt;br/&gt;&lt;br/&gt;iCloud Storageは、iDiskと違ってファイルシステムにマウントされません。そのため、FinderからはiCloud Storageのファイルを基本的に見る事はできません。ただし、iCloud Storage内のファイルはローカルにキャッシュされるようになっており、実際にはこのキャッシュファイルを読み書きすることで、間接的にiCloud Storageのファイルをアクセスします。このキャッシュファイルは、デーモンプロセスによりiCloud Storage内のファイルと同期が取られます。&lt;br/&gt;&lt;br/&gt;iCloud Storageにファイルを保存するには、一度ローカルに普通にファイルを書き出したあと、&lt;code&gt;NSFileManager&lt;/code&gt;の&lt;code&gt;setUbiquitous:itemAtURL:destinationURL:error:&lt;/code&gt;メソッドで、iCloud Storage（のキャッシュエリア）にファイルを移動させます。&lt;br/&gt;逆に、ファイルを開くときは、&lt;code&gt;NSMetadataQuery&lt;/code&gt;のスコープに&lt;code&gt;NSMetadataQueryUbiquitousDocumentsScope&lt;/code&gt;などの値を設定して、ファイル検索を行いURLを取得します。&lt;br/&gt;iCloud Storage内には自由にフォルダ（ディレクトリ）を作ることができますが、Documentsフォルダ配下に置いたファイルだけは、システム環境設定のiCloudのストレージ管理で見る事ができます。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20111029-2.png&quot;/&gt;&lt;br/&gt;&lt;br/&gt;iCloud Storageのファイルを取り扱う上で最も大変なのが、ファイルの競合解決です。これに関連して、ファイルは必ずバージョン管理しなくてはなりません。そのために、&lt;code&gt;NSFilePresenter&lt;/code&gt;の実装と、&lt;code&gt;NSFileCoordinator&lt;/code&gt;や&lt;code&gt;NSFileVersion&lt;/code&gt;の使用は不可欠です。&lt;code&gt;NSDocument&lt;/code&gt;には、これらのものが既に実装されていますが、今回のサンプルコードでは&lt;code&gt;NSDocument&lt;/code&gt;を使わずに手動で実装してみました。&lt;br/&gt;なお、iCloud Storageに保存されるのは、現在のバージョンのみなので、歴代のバージョンはそれぞれのデバイスのローカルに保存されるだけで同期されません。&lt;br/&gt;&lt;br/&gt;ちなみに、一般的に「クラウドコンピューティング」というものには、インターネット全体を１台の巨大なコンピュータにするという概念があります。インターネット経由でiCloud Storageに接続された各デバイスも、この巨大なコンピュータの一部です。&lt;br/&gt;そのため、実はファイルの同期どころか、ファイルの共有すらしていないことになります。１台のコンピュータが１つのファイルをアクセスしてるだけなので。当然、ファイルの競合など起こるはずがありません。&lt;br/&gt;そういった背景からか、iCloud Storageのドキュメントでは、ファイルの競合は可能な限り静かに解決することが推奨されています。ユーザーに競合の解決を求めるのは最後の手段です。&lt;code&gt;NSDocument&lt;/code&gt;には、この最後の手段が実装されています。&lt;/p&gt;</description>
			<pubDate>Sat, 29 Oct 2011 15:22:04 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20111029.html</guid>
		</item>
		
		<item>
			<title>MIDIWindシーケンサの開発状況</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20111009.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;今年の４月から開発を開始したMIDIWindシーケンサの今の状況はこんな感じです。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20111009.png&quot; width=&quot;480&quot; height=&quot;360&quot;/&gt;&lt;br/&gt;まだまだ未完成ですが、それっぽい形が出来上がってきたところです。&lt;br/&gt;MIDIファイルの中身が表示されて、再生もできますが、編集機能はまだありません。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Sun, 09 Oct 2011 15:43:59 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20111009.html</guid>
		</item>
		
		<item>
			<title>オーバーレイなScrollerは、少し手間</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20110901.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;オーバーレイ・スクローラーは、MacOSX10.7で大きく変化したユーザーインターフェースの一つです。&lt;br/&gt;今まで&lt;code&gt;NSScrollView&lt;/code&gt;の&lt;code&gt;documentView&lt;/code&gt;に隣接して配置されていた&lt;code&gt;NSScroller&lt;/code&gt;が、&lt;code&gt;documentView&lt;/code&gt;の上に半透明で重ね置きされるようになりました。&lt;br/&gt;この&lt;code&gt;NSScroller&lt;/code&gt;は、複合ビューである&lt;code&gt;NSScrollView&lt;/code&gt;に含まれており、特別な苦労もなく簡単に利用することができます。しかし、特殊なスクロール環境を作るために単体で&lt;code&gt;NSScroller&lt;/code&gt;を使おうとすると、単純に&lt;code&gt;NSScroller&lt;/code&gt;をView上に配置するだけで済んでいた以前と比べて、数倍もの手間が掛かことが分かりました。&lt;br/&gt;&lt;br/&gt;まず、スクローラーのスタイルとして「オーバーレイ」と「レガシー」が選択できるようになっています。そして、この２つのスタイルを任意のタイミングで切り替えられるようにしなければなりません。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110901-1.png&quot; width=&quot;480&quot; height=&quot;300&quot;/&gt;&lt;br/&gt;Lionのスクローラーは必ず「オーバーレイ」スタイルになるわけではなく、入力デバイスによってスタイルが変化します。また、システム環境設定によって手動で切り替えることもできます。その際は、アプリケーションの実行中であっても、リアルタイムに設定が反映されなければなりません。例えば、MagicMouseを使っていて突然電池が切れ、普通のUSBマウスに切り替えたとき、スクローラーが隠れたままだとスクロール不能になってしまいます。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110901-2.png&quot; width=&quot;480&quot; height=&quot;432&quot;/&gt;&lt;br/&gt;この設定変更通知を受け取るために、&lt;code&gt;NSPreferredScrollerStyleDidChangeNotification&lt;/code&gt;が用意されました。現在のスタイル情報は&lt;code&gt;[NSScroller preferredScrollerStyle]&lt;/code&gt;で取得できます。&lt;/p&gt;&lt;pre&gt;@implementation MyScrollView&lt;br/&gt;&lt;br/&gt;@synthesize documentView, scroller;&lt;br/&gt;&lt;br/&gt;- (id)initWithFrame:(NSRect)frame&lt;br/&gt;{&lt;br/&gt;  ...&lt;br/&gt;  [[NSNotificationCenter defaultCenter]&lt;br/&gt;    addObserver:self selector:@selector(styleChange:) &lt;br/&gt;    name:NSPreferredScrollerStyleDidChangeNotification object:nil];&lt;br/&gt;  ...&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (void)styleChange:(NSNotification*)notify&lt;br/&gt;{&lt;br/&gt;  NSScrollerStyle style = [NSScroller preferredScrollerStyle];&lt;br/&gt;  scroller.scrollerStyle = style;&lt;br/&gt;  scroller.frame = scrollerRectForStyle(style);&lt;br/&gt;  documentView.frame = documentRectForStyle(style);&lt;br/&gt;  [self setNeedsDisplay:YES];&lt;br/&gt;}&lt;/pre&gt;&lt;p&gt;スタイルの変更は、スクローラーのプロパティ変更だけにとどまらず、ビューの配置変更を伴います。&lt;br/&gt;&lt;br/&gt;このようなスタイル変更だけならまだ楽だったのですが、少し大変なのが「スクローラーを隠す」処理です。&lt;br/&gt;オーバーレイなスクローラーはドキュメントの一部を覆い隠しており、そのためにドキュメントの一部は画面に表示されていても見えず、しかもマウスクリックにも反応しなくなっているのです。オーバーレイなスクローラーは、必要の無い時は隠れていなくてはならないのです。&lt;br/&gt;しかし、スクローラーを隠す処理は自動的には行われません。手動で実装する必要があります。最も簡単な実装方法は&lt;code&gt;-[NSView setHidden:]&lt;/code&gt;を使う事です。でも、もう少し本格的に実装しようとしたとき問題となるのが、スクローラーの「ノブ」と「スロット」を独立して透過処理する方法です。&lt;br/&gt;オーバーレイなスクローラーは、常時隠れていて、ビューがスクロールするときのみ「ノブ」が表示され、そこでさらにマウスをスクローラーにフォーカスさせると「スロット」が表示される仕組みです。しかし、以前よりスクローラーのノブとスロットは一体もので、ノブのみを表示させるようなAPIはMacOSX10.7のリファレンスにも載っていません。&lt;br/&gt;&lt;br/&gt;このノブとスロットの独立透過処理をプライベートな領域に片足を入れて実装すると以下のようになります。&lt;/p&gt;&lt;pre&gt;- (void)hideSlot&lt;br/&gt;{&lt;br/&gt;  [NSAnimationContext beginGrouping];&lt;br/&gt;  NSAnimationContext* animeContext = [NSAnimationContext currentContext];&lt;br/&gt;  [animeContext setDuration:0.25];&lt;br/&gt;  id animeProxy = [scroller animator];&lt;br/&gt;  NSNumber* alphaValue = [NSNumber numberWithDouble:0.0];&lt;br/&gt;  [animeProxy setValue:alphaValue forKey:@&quot;overlayScrollerTrackAlpha&quot;];&lt;br/&gt;  [NSAnimationContext endGrouping];&lt;br/&gt;}&lt;/pre&gt;&lt;p&gt;これを実行すると、スクローラーのスロットのみが0.25秒かけてなめらかに透明になっていきます。&lt;code&gt;&quot;overlayScrollerTrackAlpha&quot;&lt;/code&gt;の代わりに&lt;code&gt;&quot;overlayScrollerKnobAlpha&quot;&lt;/code&gt;というキーを使うと、ノブとスロットを合わせた透明度をアニメーション付きで制御できます。&lt;br/&gt;上記のコードは一応プライベートなAPIを一切使用していませんが、&lt;code&gt;&quot;overlayScrollerTrackAlpha&quot;&lt;/code&gt;などのキーの使用を許容するかどうかで議論が分かれるかもしれません。&lt;br/&gt;&lt;br/&gt;プライベートな領域に一切触れずに実装するなら、以下のように&lt;code&gt;NSScroller&lt;/code&gt;のサブクラスを作って、&lt;code&gt;drawRect:&lt;/code&gt;をオーバーライドしなければなりません。&lt;/p&gt;&lt;pre&gt;@interface MyScroller : NSScroller&lt;br/&gt;@property(readwrite) CGFloat knobAlphaValue;&lt;br/&gt;@property(readwrite) CGFloat trackAlphaValue;&lt;br/&gt;@end&lt;br/&gt;&lt;br/&gt;@implementation MyScroller&lt;br/&gt;@synthesize knobAlphaValue, trackAlphaValue;&lt;br/&gt;&lt;br/&gt;+ (BOOL)isCompatibleWithOverlayScrollers&lt;br/&gt;{&lt;br/&gt;  return self == [MyScroller class];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (void)drawRect:(NSRect)dirtyRect&lt;br/&gt;{&lt;br/&gt;  [[NSColor clearColor] set];&lt;br/&gt;  NSRectFill(NSInsetRect([self bounds], -1.0, -1.0));&lt;br/&gt;  CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];&lt;br/&gt;  CGContextSaveGState(context);&lt;br/&gt;  CGContextSetAlpha(context, trackAlphaValue);&lt;br/&gt;  NSRect knobSlotRect = [self rectForPart:NSScrollerKnobSlot];&lt;br/&gt;  [self drawKnobSlotInRect:knobSlotRect highlight:NO];&lt;br/&gt;  CGContextSetAlpha(context, knobAlphaValue);&lt;br/&gt;  [self drawKnob];&lt;br/&gt;  CGContextRestoreGState(context);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;@end&lt;/pre&gt;&lt;p&gt;上記のコードでは、&lt;code&gt;knobAlphaValue&lt;/code&gt;と&lt;code&gt;trackAlphaValue&lt;/code&gt;の２つのプロパティによって、ノブとスロットの透明度を独立して設定できるようになっています。あとは、&lt;code&gt;NSAnimation&lt;/code&gt;を使って透明度を制御すれば、先ほどと同じようなものが実現します。&lt;br/&gt;なお、&lt;code&gt;NSScroller&lt;/code&gt;をオーバーレイ対応でサブクラス化する場合は、上記のような形で&lt;code&gt;isCompatibleWithOverlayScrollers&lt;/code&gt;を実装する必要があります。ここで&lt;code&gt;YES&lt;/code&gt;を返さないと、オーバーレイは無効です。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Thu, 01 Sep 2011 19:55:41 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20110901.html</guid>
		</item>
		
		<item>
			<title>IPv6がやってきた！</title>
			<link>http://www.stripe-net.jp/cocoa/admin/blog20110820.html</link>
			<category>サーバー運営</category>
			<description>&lt;p&gt;６月から各プロバイダ一斉にIPv6のネイティブ接続サービスがスタートしました。うちのOCNもPPPoEのIPv6接続を無料のオブションサービスという形で提供を開始したので、早速申し込みしました。&lt;br/&gt;&lt;br/&gt;それで、OCN側の工事は６月下旬には終わっていたのですが、YAMAHAのルーター(RTX1200)の対応が遅れて、やっとIPv6のPPPoE接続に対応したのが７月下旬。そこから、ルーターの設定で、いろいろ苦労があって、実際の使用開始は８月上旬となってしまいました。&lt;br/&gt;まあ、別に急いでいたわけじゃないから、どんなに遅れてもいいんだけどね。&lt;br/&gt;&lt;br/&gt;ちなみに、OCNの申込書には「別途、NTTのIPv6トンネル対応アタブタが必要です。」と書かれていましたが、YAMAHAのRTX1200があれば不要です。一応買ってしまいましたが。&lt;br/&gt;&lt;br/&gt;それから、参考までにルーターのコンフィグはこんな感じです。&lt;/p&gt;&lt;/p&gt;&lt;pre&gt;# RTX1200 Rev.10.01.32 (Wed Jul 13 17:42:17 2011)&lt;br/&gt;ipv6 route default gateway pp 1&lt;br/&gt;ipv6 prefix 1 2400:xxxx:xxxx:11::/64&lt;br/&gt;ipv6 prefix 2 2400:xxxx:xxxx:22::/64&lt;br/&gt;ipv6 vlan1 prefix 2400:xxxx:xxxx:11::/64&lt;br/&gt;ipv6 vlan1 rtadv send 1 o_flag=on&lt;br/&gt;ipv6 vlan2 prefix 2400:xxxx:xxxx:22::/64&lt;br/&gt;ipv6 vlan2 rtadv send 2 o_flag=on&lt;br/&gt;pp select 1&lt;br/&gt; pppoe use lan3&lt;br/&gt; pp auth accept pap chap&lt;br/&gt; pp auth myname xxxx xxxx&lt;br/&gt; ppp ccp type none&lt;br/&gt; ppp ipv6cp use on&lt;br/&gt; ipv6 pp secure filter in 1 2 3 4 5&lt;br/&gt; ipv6 pp dhcp service client&lt;br/&gt; pp enable 1&lt;br/&gt;ipv6 filter 3 pass * * * * 546-547&lt;/pre&gt;&lt;p&gt;&lt;p&gt;設定のポイントは、&lt;/p&gt;&lt;ul&gt;&lt;li&gt;「&lt;code&gt;ipv6 route default gateway pp 1&lt;/code&gt;」で、ppをゲートウエイにする。&lt;/li&gt;&lt;li&gt;「&lt;code&gt;ppp ipv6cp use on&lt;/code&gt;」で、ipv6cpを有効にする。&lt;/li&gt;&lt;li&gt;「&lt;code&gt;ipv6 pp dhcp service client&lt;/code&gt;」で、DHCPv6を有効にする。&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;といったところです。&lt;br/&gt;今回は、プロバイダから/56のアドレスを固定で割当てもらっているので、LAN側のアドレスは手動で設定しています。アドレスの割当が/64の場合は、DHCPv6で受信したアドレスをそのままLAN側に割り当ててください。&lt;br/&gt;ちなみに、NTTのIPv6トンネル対応アダブタだと、/64のアドレスしか対応していないようなので、今回は本当に使い物になりませんでした。&lt;br/&gt;&lt;br/&gt;IPv4のPPPoE接続のときは、unnumbered接続だったので、ただ単純にppをゲートウエイにするだけでよかったのですが、IPv6のPPPoE接続の場合は、ppでDHCPv6を稼働させてアドレスを受信しないと正常に繋がらないようです。ppにフィルターを設定する場合はDHCPv6のパケットが通るようにポート546-547に穴を開けてください。&lt;br/&gt;今回は、このDHCPv6の設定に気づかず苦労したというのもありますが、設定に気づいてDHCPv6のコンフィグを投入したのに、なぜかDHCPv6が正常に稼働しなかったため、泥沼にはまってしまいました。&lt;br/&gt;ルーターの電源をOFF/ONしてもダメで、最終的にはcoldstartでルーターを初期化してからコンフィグを入れ直して、やっと正常に稼働するようになりました。&lt;br/&gt;&lt;br/&gt;サーバーの方は、HTTPとDNSだけIPv6で見えるようにしているつもりですが、未確認です。なにぶん、IPv6の回線が１本しかないので、外部からの接続試験ができません。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Sat, 20 Aug 2011 22:26:12 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/admin/blog20110820.html</guid>
		</item>
		
		<item>
			<title>Lionの新機能を使ったサンプルコード</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20110804.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;非同期保存などのMacOSX10.7の新機能が気になったので、&lt;a href=&quot;http://www.stripe-net.jp/cocoa/downloads/lion_sample1.zip&quot;&gt;サンプルコード&lt;/a&gt;を作って見ました。&lt;br/&gt;&lt;br/&gt;まず、一番簡単なのはフルスクリーンモード。単純に&lt;code&gt;NSWindow&lt;/code&gt;のプロパティでFull ScreenをPrimary Windowに設定するだけで、ウインドウの右上にフルスクリーンボタンが付きます。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110804-1.png&quot; width=&quot;420&quot; height=&quot;340&quot;/&gt;&lt;br/&gt;&lt;br/&gt;つぎに、Auto Layout。当初、XcodeではGUIでの編集がサポートされていないと思っていましたが、実はサポートされていました。しかし、分かりづらい。&lt;br/&gt;.xibファイルのプロパティで、「Use Auto Layout」にチェックを入れると、レイアウトの編集が通常モードからAuto Layoutモードへと切り替わります。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110804-2.png&quot; width=&quot;368&quot; height=&quot;400&quot;/&gt;&lt;br/&gt;Editorメニュー配下にPinメニューがが追加されて、これで&lt;code&gt;NSLayoutConstraint&lt;/code&gt;オブジェクトが追加できるようになります。&lt;br/&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110804-3.png&quot; width=&quot;480&quot; height=&quot;315&quot;/&gt;&lt;br/&gt;Auto LayoutではPriorityという、そのレイアウトをどの程度強制するのかを示すプロパティの使い方がポイントのようです。例えば、自由にリサイズするビュー内部をレイアウトするとき、すべてを&lt;code&gt;Priority=1000&lt;/code&gt;にしてしまうと、ビューのサイズが縮小し過ぎたときにレイアウトを維持できなくなる可能性があるため、実行時に警告が出たりします。&lt;br/&gt;&lt;br/&gt;そして、自動保存とバージョン管理については、プロジェクトのテンプレートにあるように&lt;code&gt; +autosavesInPlace&lt;/code&gt;で&lt;code&gt;YES&lt;/code&gt;を返すようにするだけで有効になります。&lt;p&gt;&lt;/p&gt;&lt;pre&gt;@implementation MyDocument&lt;br/&gt;&lt;br/&gt;+ (BOOL)autosavesInPlace&lt;br/&gt;{&lt;br/&gt;    return YES;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (IBAction)editModelObject:(id)sender&lt;br/&gt;{&lt;br/&gt;    [modelObject edit];&lt;br/&gt;    [self updateChangeCount:NSChangeDone];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError&lt;br/&gt;{&lt;br/&gt;    return [NSArchiver archivedDataWithRootObject:modelObject];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName &lt;br/&gt;    error:(NSError **)outError&lt;br/&gt;{&lt;br/&gt;    [self willChangeValueForKey:@&quot;modelObject&quot;];&lt;br/&gt;    modelObject = [NSUnarchiver unarchiveObjectWithData:data];&lt;br/&gt;    [self didChangeValueForKey:@&quot;modelObject&quot;];&lt;br/&gt;    return YES;&lt;br/&gt;}&lt;/pre&gt;&lt;p&gt;&lt;p&gt;&lt;code&gt;updateChangeCount:&lt;/code&gt;の呼び出しにより書類の編集が検知されると、一定時間操作が無いときにRunLoopから書類の保存が起動されます。また、「保存」メニューが「バージョンを保存」に変わります。&lt;br/&gt;&lt;code&gt;readFromData:ofType:error:&lt;/code&gt;は、通常書類を開く時に呼ばれますが、書類を古いバージョンに戻す時にも呼ばれます。古いバージョンに戻すときは、開くときと違い、&lt;code&gt;NSDocument&lt;/code&gt;オブジェクトが新規に生成されないので、ここで&lt;code&gt;didChangeValueForKey:&lt;/code&gt;などを呼んでおかないと、表示が更新されません。&lt;br/&gt;&lt;br/&gt;で、ここからが本題の非同期保存ですが、まず非同期保存を有効にするには上記のコードに加えて、&lt;code&gt;canAsynchronouslyWriteToURL:ofType:forSaveOperation:&lt;/code&gt;で&lt;code&gt;YES&lt;/code&gt;を返し、保存処理の中で&lt;code&gt;unblockUserInteraction&lt;/code&gt;を呼び出す必要があります。&lt;/p&gt;&lt;/p&gt;&lt;pre&gt;@implementation MyDocument&lt;br/&gt;&lt;br/&gt;- (BOOL)canAsynchronouslyWriteToURL:(NSURL *)url ofType:(NSString *)typeName &lt;br/&gt;    forSaveOperation:(NSSaveOperationType)saveOperation&lt;br/&gt;{&lt;br/&gt;    return YES;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError&lt;br/&gt;{&lt;br/&gt;    [self unblockUserInteraction];&lt;br/&gt;    return [NSArchiver archivedDataWithRootObject:currentObject];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (IBAction)editModelObject:(id)sender&lt;br/&gt;{&lt;br/&gt;    self.currentObject = [currentObject edit];&lt;br/&gt;    [[self undoManager] setActionName:@&quot;Edit&quot;];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (void)setCurrentObject:(Model*)object&lt;br/&gt;{&lt;br/&gt;    [[self undoManager] registerUndoWithTarget:self &lt;br/&gt;        selector:@selector(setCurrentObject:) object:currentObject];&lt;br/&gt;    currentObject = object;&lt;br/&gt;}&lt;/pre&gt;&lt;p&gt;&lt;p&gt;&lt;code&gt;canAsynchronouslyWriteToURL:ofType:forSaveOperation:&lt;/code&gt;で&lt;code&gt;YES&lt;/code&gt;を返すことによって、&lt;code&gt;dataOfType:error:&lt;/code&gt;がメインスレッドとは別のスレッドで呼ばれるようになります。ただし、このときメインスレッドは、このスレッドに&lt;code&gt;join&lt;/code&gt;するような形でブロックされているため、この時点ではまだ非同期ではありません。&lt;code&gt;unblockUserInteraction&lt;/code&gt;を呼ぶことで、メインスレッドのブロックが解除されて、ここから非同期保存が始まります。&lt;br/&gt;&lt;br/&gt;このように、非同期にするだけなら簡単なのですが、問題は「非同期保存中に、メインスレッドで書類が編集されたらどうするか？」です。これに対する基本戦略は、「非同期になる前に、書類のスナップショットを取る」です。&lt;code&gt;unblockUserInteraction&lt;/code&gt;が呼ばれるまで非同期にならないのは、スナップショットを取る最後のチャンスを与えるためです。&lt;br/&gt;しかし、スナップショットとは、ようするに書類全体のコピーを作る処理のことです。ここであまり処理に時間を掛けると、非同期のメリットが失われてしまいます。&lt;br/&gt;&lt;br/&gt;今回はこれらの問題に対し、イミュータブルな戦略を試してみました。つまり、&lt;code&gt;NSArray&lt;/code&gt;にオブジェクトを追加する際に、&lt;code&gt;-[NSMutableArray addObject:]&lt;/code&gt;を使わず、代わりに&lt;code&gt;-[NSArray arrayByAddingObject:]&lt;/code&gt;を使うということです。書類を編集する全てのメソッドで、新規に生成された編集後の書類オブジェクトを返すようにしています。&lt;/p&gt;&lt;/p&gt;&lt;pre&gt;@interface Model&lt;br/&gt;&lt;br/&gt;- (Model*)addNewPerson;&lt;br/&gt;- (Model*)removeAtIndex:(NSUInteger)index;&lt;br/&gt;- (Model*)setNameValue:(NSString*)name atIndex:(NSUInteger)index;&lt;br/&gt;- (Model*)setAgeValue:(NSInteger)age atIndex:(NSUInteger)index;&lt;br/&gt;- (Model*)setCommentValue:(NSString*)comment atIndex:(NSUInteger)index;&lt;br/&gt;&lt;/pre&gt;&lt;p&gt;&lt;p&gt;この方法だと、実質的に常時スナップショットを取っている形になるので、保存処理でいきなり非同期にしても問題ありません。これは、平行処理に強いと言われている関数型言語で標準的に行われている方法です。&lt;br/&gt;&lt;br/&gt;さらに、このイミュータブルな戦略を使った際の二次的な効果として、Undo処理が簡素で信頼性の高いものになるというのがあります。&lt;br/&gt;CocoaのUndoは、基本的には「書類の操作履歴」です。ある操作をしたとき、それとは逆の操作をすれば元に戻るという話です。しかし、この方法には少し問題もあります。まず、Undoのために必ず対となる操作を作らなければならないこと、それから、操作を操作で打ち消す場合、書類が確実に元の状態に戻る保証がないことです。例えば、「値を３で割る」という操作を「値を３倍する」という操作で打ち消そうとしても、端数処理の関係で元の値に戻らないかもしれません。&lt;br/&gt;今回のUndoは「書類の状態履歴」という形で実装しています。書類を操作したときに捨てられるはずの古いスナップショットを、Undoとして登録するだけの簡単な実装です。これだと、Undoのために対になる操作を作る必要もないし、Undoすれば確実に元の状態に戻ります。&lt;br/&gt;&lt;br/&gt;最後に、今回スナップショットにイミュータブルな戦略を採用した結果、バインドが使いにくくなることが分かりました。そもそもCocoaではミュータブルな戦略が採用されているので、イミュータブルな戦略とはやや相性が悪いのです。しかし、「非同期」や「平行処理」をキーワードにプログラムを書くなら、イミュータブルな戦略を採用した方が有利に展開するのは、今回のサンプルコードからも明らかです。&lt;br/&gt;Cocoaは最初にリリースされてからもう10年以上立ちました。そろそろ時代遅れなものになりつつあるのかもしれませんね。&lt;/p&gt;</description>
			<pubDate>Thu, 04 Aug 2011 22:51:56 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20110804.html</guid>
		</item>
		
		<item>
			<title>MIDIWind2.1.1をリリース</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20110727.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;MIDIWind2.1.1をリリースしました。&lt;br/&gt;単純にMacOSX10.7に対応させただけで、特に追加機能はありません。また、このバージョンから動作環境が10.6以降となりました。&lt;br/&gt;&lt;br/&gt;10.7で動作上問題となったのが内蔵のソフトシンセで、Deprecatedな古いAPIを使用するとアプリごとクラッシュしてしまいます。また、なぜかコントロールチェンジ#93（コーラスエフェクト）を送るとフリーズします。&lt;br/&gt;&lt;br/&gt;今回のアップグレードで、Deprecatedな古いAPIを10.6の新しいAPIに書き替え、余計なコントロールチェンジを送信しないようにフィルターを施しています。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Wed, 27 Jul 2011 20:23:58 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20110727.html</guid>
		</item>
		
		<item>
			<title>LionそしてMIDIWindがまた動かなく...</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20110723.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;OSをMacOSX10.7(Lion)にアップグレードしました。&lt;br/&gt;そして、またしてもMIDIWind2.1の一部の機能が動かなくなりました。&lt;br/&gt;&lt;br/&gt;ソフトシンセで再生しようとすると、アプリケーションが予期せず落ちてしまいます。&lt;br/&gt;幸い外部音源の再生は問題なくできるようです。&lt;br/&gt;&lt;br/&gt;MIDIWind2.1はMacOSX10.4がターゲットで、ソフトシンセ周りでDeprecatedなAPIを使っていて、このAPIがLionで使用不能にならないことを祈っていたのですが、残念ながらその祈りはAppleには届かなかったようです。&lt;br/&gt;これから、10.7対応に修正する予定です。&lt;br/&gt;&lt;br/&gt;MacOSX10.7でも新しいAPIがいろいろ追加されていますが、ジェスチャー・フルスクリーン・自動保存＆バージョンなんかが大きなところかな。まだ詳しく見ていないが、自動保存に伴う「非同期保存」の実装が少し気になるところだ。保存中にデータを書き換えたらどうなるんだろうか？　あと、CoreDataの自動保存ってどうなるんだろ？　自動保存関連の機能追加が無いように見える。&lt;br/&gt;その他にも、TableViewでCellの代わりにViewが使えるようになった。今まではMatrixを使った実装だったので同じcellを並べることしかできませんでしたが、Viewだと行ごとに違うものを使ったりとか出来るっぽい。単純にデータをリスト表示するのとは違うものが作れそうだ。&lt;br/&gt;それから、新しいViewのレイアウト機能が追加された。でも、Xcodeが対応していないっぽく、コードを書いてレイアウトしなきゃならないっぽい。なんか不便だ。&lt;br/&gt;&lt;/p&gt;</description>
			<pubDate>Sat, 23 Jul 2011 02:19:42 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20110723.html</guid>
		</item>
		
		<item>
			<title>Viewを如何にテストするか？</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20110530.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;テストにはテスト内容に応じていろいろな種類や方法がありますが、オブジェクト単位のシンプルな機能テストと言えばxUnitなどを使うユニットテストがあります。オブジェクトに何かを入力したときの出力を検査することで、オブジェクトの機能をテストするというものです。&lt;br/&gt;&lt;br/&gt;MVCパターンに基づいてコードを書いている場合、Modelが最もテストし易いコンポーネントになります。Modelは他のコンポーネントに依存しない形になっているので、テストプログラムに組み込むことも簡単なのです。&lt;br/&gt;逆に、ViewやControllerはテストしにくいコンポーネントです。まあ、ViewやControllerに限らず、I/O処理を含むコードのテストはModelであっても困難です。ただModelであればまだ手段がありますが、特にViewに関してはグラフィックの描画という部分がOSに結び付いているため、この部分のテストを行うのは非常に困難です。&lt;br/&gt;&lt;br/&gt;でも、だからといってViewをテストしないわけにも行きません。&lt;br/&gt;まず最初に考えたのは、グラフィックの描画そのものをテストすることはできないが、描画に使用するパラメータならテストできるのではないか、という事です。例えば、&lt;code&gt;NSRectFill()&lt;/code&gt;で塗りつぶす時に矩形の座標情報がパラメータとして必要になります。塗りつぶした結果はテストできないかもしれませんが、矩形の座標情報ならテスト可能ですし、それをテストすれば塗りつぶした結果を間接的にテストしたことになるのでしょう。&lt;br/&gt;しかしこの方法はうまく行きませんでした。なぜなら、Modelの場合は「テストに合格するコードが良いコード」だったのに対し、Viewの場合は「見栄えの良いグラフィックを描画するコードが良いコード」だからです。グラフィックは実際に画面に表示させて見ないと評価できません。座標情報を前もって決めておくことは困難なのです。&lt;br/&gt;&lt;br/&gt;このように、グラフィックの描画がViewの主要機能であるにもかかわらず、それをテストすることが現実的ではないとすると、そもそもViewの何をテストすればいいのでしょうか。いろいろ考えた結果、おそらく以下のようなものがテストの対象になるのでしょう。&lt;br/&gt;&lt;br/&gt;・ViewがModelオブジェクトにアクセスできるか？&lt;br/&gt;・ViewがModelオブジェクトからの通知を受け取れるか？&lt;br/&gt;・ViewがNSEventを受け取りTarget/Actionを発行できるか？&lt;br/&gt;&lt;br/&gt;しかし、これはこれで難しいデストです。通常ユニットデストでは、あるものを入力したときの出力をテストしますが、上記のような場合は出力されるものがありません。そこで、これをテストするために、以下のような方法を考えました。&lt;/p&gt;&lt;/p&gt;&lt;pre&gt;@interface TestView : MyView {&lt;br/&gt;  NSMutableArray* log;&lt;br/&gt;}&lt;br/&gt;@property(retain) NSMutableArray* log;&lt;br/&gt;&lt;br/&gt;@end&lt;br/&gt;&lt;br/&gt;@implementation TestView&lt;br/&gt;&lt;br/&gt;@synthesize log;&lt;br/&gt;&lt;br/&gt;- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object &lt;br/&gt;  change:(NSDictionary *)change context:(void *)context {&lt;br/&gt;  [log addObject:@&quot;observeValueForKeyPath&quot;];&lt;br/&gt;  [super observeValueForKeyPath:keyPath ofObject:object&lt;br/&gt;    change:change context:context];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;- (void)setNeedsDisplay:(BOOL)flag {&lt;br/&gt;  [log addObject:@&quot;setNeedsDisplay&quot;];&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;@end&lt;br/&gt;&lt;br/&gt;@implementation MyTestCase&lt;br/&gt;&lt;br/&gt;- (void)testKeyValueObserv {&lt;br/&gt;  MyModel* model = [[MyModel alloc] init];&lt;br/&gt;  TestView* view = [[TestView alloc] initWithFrame:NSZeroRect];&lt;br/&gt;  [view bind:@&quot;content&quot; toObject:model withKeyPath:@&quot;self&quot; options:nil];&lt;br/&gt;  view.log = [[NSMutableArray alloc] init];&lt;br/&gt;  [model setValue:@&quot;hoge&quot; forKey:@&quot;boke&quot;];&lt;br/&gt;  STAssertEqualObjects(&lt;br/&gt;    [view.log objectAtIndex:0], @&quot;observeValueForKeyPath&quot;, nil);&lt;br/&gt;  STAssertEqualObjects(&lt;br/&gt;    [view.log objectAtIndex:1], @&quot;setNeedsDisplay&quot;, nil);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;@end&lt;/pre&gt;&lt;p&gt;&lt;p&gt;これは、テスト対象のViewオブジェクトに、メソッド呼び出しのログを取る機能を追加して、ユニットテストを行うという方法です。このテストにより、Modelオブジェクトのプロパティが変化したときに、Viewがその通知を受け取って再描画しようとしている動きをテストできます。&lt;br/&gt;&lt;br/&gt;メソッドの呼び出しがログという形で出力されるので、通常のユニットテストでもテスト可能になります。また、上記の例では&lt;code&gt;setNeedsDisplay:&lt;/code&gt;の呼び出しで&lt;code&gt;super&lt;/code&gt;を呼んでいないので、実際にグラフィックの描画というI/O処理が発生しません。&lt;br/&gt;&lt;br/&gt;これにより、Viewのテストができる見通しがたったものの、メソッドのログを取るためにいちいちサブクラスを書くのはちょっと面倒。でも、このようなことは、アスペクト指向を使えば簡単なのですが、残念ならがObjective-Cにはアスペクト指向の実装がありません。昔は、あったらしいですけどね、なんとなく復活してくれるとうれしいです。&lt;/p&gt;</description>
			<pubDate>Mon, 30 May 2011 19:11:37 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20110530.html</guid>
		</item>
		
		<item>
			<title>MIDIWindシーケンサの開発開始</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20110423.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;予定どおり現在MIDIWindシーケンサを開発中です。MIDIWindシーケンサは、ようするにSMFファイルの編集ソフトです。ピアノロールやイベントリスト、リアルタイム入力なんかを予定。&lt;br/&gt;&lt;br/&gt;Xcode4になってUnitTestが使いやすくなったので、今回の開発ではテストファーストを実践しています。テストファーストとは、先にテストコードを書いてから、そのテストに合格するように本体コードを書く開発スタイルのことです。今のところ、少々ぎこちないながらもなんとか形になっている状況です。噂どおり、テストを全てクリアするのを見るのは、なんだか楽しいですね。&lt;br/&gt;&lt;br/&gt;それから、プロジェクトの管理に&lt;a href=&quot;http://redmine.jp/&quot;&gt;Redmine&lt;/a&gt;を使い始めました。RedmineはRubyで作られたWebアプリケーションで、うちではApache2 + mod_passenger + MySQL5の組み合わせで運用しています。Redmineでは「チケット」を使ってプロジェクトを管理します。リポジトリのリビジョンをチケットに関連付けることもできます。&lt;br/&gt;そして、この&lt;a href=&quot;http://www.stripe-net.jp/coding-manager/projects/midiwind3&quot;&gt;MIDIWindのプロジェクト&lt;/a&gt;は公開することにしました。リポジトリも公開するので、コミットしたソースコードをリアルタイムに見る事ができます。&lt;br/&gt;&lt;br/&gt;MIDIWindプレイヤーの方は、MacAppStoreに出して見ました。無料なので、開発者側に金銭的なメリットは無いですが、ユーザー側にAppStoreのソフトが充実することへのニーズがあるなら、それに答えてもいいかなと思いました。それに、AppStoreに並ぶソフトが有料ソフトばかりというのも、ちょっと寂しいですしね。&lt;/p&gt;</description>
			<pubDate>Sat, 23 Apr 2011 19:57:59 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20110423.html</guid>
		</item>
		
		<item>
			<title>CocoaにおけるMVCパターンの実装</title>
			<link>http://www.stripe-net.jp/cocoa/update/blog20110405.html</link>
			<category>サイト更新情報</category>
			<description>&lt;p&gt;Cocoaの記事を書きました。今回は、&lt;a href=&quot;http://www.stripe-net.jp/cocoa/documents/chapter5/chapter5-1.html&quot;&gt;MVCにおけるコントローラの実装&lt;/a&gt;ということで、MVCパターンの話です。&lt;br/&gt;アプリケーションの規模が大きくなると、全体構成をどうするかとか、どこに何を書くのかをある程度整理しておかないと、あっという間にスパゲティーが出来上がります。CocoaはMVCパターンをベースにしたフレームワークなので、とりあえずMVCパターンに従って実装すれば、それほど悪い状態にはならないはずです。&lt;br/&gt;ただ、実際にはModelの内部構成なんかについても整理しないと、十分とは言えないかもしれませんが、そこまで話を広げて整理しようとするとかなり大変な事になるので、今回はControllerに的を絞って整理しました。MVCで比較的厄介なのがControllerであると思われるので、ここを重点的に整理すれば、あとはまあ何とかなるでしょう。&lt;/p&gt;</description>
			<pubDate>Tue, 05 Apr 2011 20:57:24 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/update/blog20110405.html</guid>
		</item>
		
		<item>
			<title>Xcode4でNSLogを過去にする</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20110319.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;Xcode4がリリースされました。久しぶりの大幅なアップグレードです。InterfaceBuilderと統合されて、ユーザーインターフェースもガラッと変わっています。強化された機能もいろいろありますが、今回はその中でブレークポイントを紹介します。&lt;br/&gt;&lt;br/&gt;今までデバックする際に、あるメソッドは確実に呼ばれているか？　ある時点での変数の値はどうか？&lt;br/&gt;ということを確認するのに、ブレークポイントを設定する方法もありましたが、それだとプログラムの実行がいちいち止まってしまい、デバックの効率が非常に悪くなることがありました。ループ処理の内部に興味がある場合は特にそうです。&lt;br/&gt;そのため、ブレークポイントを設定する代わりに&lt;code&gt;NSLog()&lt;/code&gt;をプログラムに挿入して実行し、デバッグが終わったら&lt;code&gt;NSLog()&lt;/code&gt;を削除する。などということを行って来ました。&lt;br/&gt;&lt;br/&gt;しかし、Xcode4からは一時的なデバックのために&lt;code&gt;NSLog&lt;/code&gt;を使う必要はもうありません。ブレークポイント・アクションの機能が（少しだけ）強化されたからです。&lt;br/&gt;&lt;br/&gt;まず、ソースコードの左側をクリックして、ブレークポイントを設定します。&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110319-1.png&quot; width=&quot;480&quot; height=&quot;160&quot;/&gt;&lt;p&gt;&lt;br/&gt;次に、ブレークポイントを右クリック（Control+クリック）して、メニューを開き、「Edit Breakpoint」を選択します。&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110319-2.png&quot; width=&quot;480&quot; height=&quot;160&quot;/&gt;&lt;p&gt;&lt;br/&gt;すると、情報パネルらしきものが開かれるので、そこで「Click to add an action」をクリックしてアクションを追加します。&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110319-3.png&quot; width=&quot;480&quot; height=&quot;154&quot;/&gt;&lt;p&gt;&lt;br/&gt;ここで、Actionに「Log Message」を選択。テキストフィールドに出力するメッセージ”MyView %B (%H) @(NSPoint)[theEvent locationInWindow]@”を入力します。そして、忘れずにOptionsの「Automatically continue after evaluating actions」にチェックを入れます。（これが追加機能です）&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110319-4.png&quot; width=&quot;480&quot; height=&quot;254&quot;/&gt;&lt;p&gt;最後に「Done」をクリックすれば完了です。&lt;br/&gt;&lt;br/&gt;出力するメッセージの文字列では、「%B」がブレークポイントの名前、「%H」がブレークポイントを通過した回数に置き換えられます。また「@...@」で式を書くことができますが、ここにはObjective-Cのメソッド呼び出しを書く事もできます。「(NSPoint)」などと戻り値をキャストすれば、構造体も出力可能です。&lt;br/&gt;&lt;br/&gt;今回はNSViewのmouseDown:にブレークポイントを設定した訳ですが、これでプログラムを実行すると、Viewをクリックするたびにコンソールにログが出力されます。&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110319-5.png&quot; width=&quot;480&quot; height=&quot;388&quot;/&gt;&lt;p&gt;メニューでProduct＞Window Behavior＞Xcode In Frontを選択しておくと、デバック時のみXcodeがコンソールのみ小さなウインドウに縮小され、常に手前に表示されるようになります。&lt;/p&gt;</description>
			<pubDate>Sat, 19 Mar 2011 18:19:55 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20110319.html</guid>
		</item>
		
		<item>
			<title>MIDIWind version2.1をリリース</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20110220.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;&lt;a href=&quot;http://www.stripe-net.jp/cocoa/downloads/midiwind_player2.1.zip&quot;&gt;MIDIWind Player Edition v2.1&lt;/a&gt;をリリースしました。&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20110220.png&quot; width=&quot;480&quot; height=&quot;287&quot;/&gt;&lt;p&gt;今回のバージョンでMacOSX10.6に対応するようになり、これでJavaのコードが全て削除されました。また、ユーザーインターフェースも大幅に修正しました。&lt;br/&gt;&lt;br/&gt;MIDIWindを作るのは、これで3回目です。バージョン1.0のリリースが2004年なので、7年も開発を続けたことになります。こんなに何度も作る予定ではなかったのですけどね。&lt;br/&gt;思えば、Cocoa-Javaを使ったのがそもそもの始まりでした。当初、JavaはMaxOSXのコアなコンポーネントと位置づけられていたので、まさかOSから削除されるとは思ってもいませんでした。&lt;br/&gt;&lt;br/&gt;以前にも書いたことがあると思いますが、MIDIWindはもともとMIDIプレイヤではなく、MIDIシーケンサを作るためのプロジェクトです。MIDIプレイヤは、MIDIデバイスへのアクセスをテストするために、シーケンサに先行して作成したに過ぎません。&lt;br/&gt;そういう訳で、今度こそMIDIWind Player Editionの開発は、バグが出ないかぎり終了にする予定です。4月ぐらいから、シーケンサとしてのMIDIWindの開発が始まるはずです。&lt;/p&gt;</description>
			<pubDate>Sun, 20 Feb 2011 16:53:30 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20110220.html</guid>
		</item>
		
		<item>
			<title>MIDI.mdimporterの罠</title>
			<link>http://www.stripe-net.jp/cocoa/program/blog20110120.html</link>
			<category>プログラミング</category>
			<description>&lt;p&gt;MacOSX10.6対応版のMIDIWindは、順調に開発が進んでいます。機能的な部分はほぼ全ての実装が終わり、今はビューの表示関係を修正して見栄えを良くしているところです。&lt;br/&gt;&lt;br/&gt;で、検索機能を実装していた中でまた妙な問題に出くわしました。それが、MIDI.mdimporterです。&lt;br/&gt;&lt;br/&gt;かつて、MIDIWind2.0の開発中に&lt;a href=&quot;http://www.stripe-net.jp/cocoa/program/blog20061202.html&quot;&gt;MIDIファイルから情報を収集するMDインポータがない&lt;/a&gt;という話になり、けっきょく&lt;a href=&quot;http://www.stripe-net.jp/cocoa/software/blog20070527.html&quot;&gt;自前でMDインポータを作った&lt;/a&gt;経緯があります。その時は、MDインポータを動かすためのUTIがMIDIファイルに定義されていなかったため、独自にUTIを定義してMDインポータを実装しました。&lt;br/&gt;&lt;br/&gt;そして現在、MacOSXにはMIDIファイルのために、public.midi-audioというUTIが定義され、それ用のMIDI.mdimporterが/System/Library/Spotlight内に用意されました。めでたしめでたし、という感じなのだが実際にはそううまくは行かなかった。どうも、MIDIファイルの検索がうまく行かない。&lt;br/&gt;&lt;br/&gt;調べて見ると、どうもこのMIDI.mdimporterは、MIDIファイルからほとんど情報を収集しないらしい。なんとも役立たずなMDインポータだ。それで、自前のMDインポータを使おうということになったのだが、これがなぜか機能しない。&lt;br/&gt;調べて見ると、同一のUTIに対するMDインポータが複数ある場合、実際に動くのは１つだけで、優先順位は&lt;br/&gt;&lt;ol&gt;&lt;li&gt;~/Library/Spotlight&lt;/li&gt;&lt;li&gt;/Library/Spotlight&lt;/li&gt;&lt;li&gt;/System/Library/Spotlight&lt;/li&gt;&lt;li&gt;MyApp.app/Contents/Library/Spotlight&lt;/li&gt;&lt;/ol&gt;こんな感じだ。&lt;br/&gt;MIDI.mdimporter、邪魔である。&lt;br/&gt;&lt;br/&gt;もちろん、自前のMDインポータを~/Library/Spotlightにインストールすればいいのだが、逆にOS標準のMDインポータをあっさり殺してしまっていいのかという懸念もある。&lt;br/&gt;で、最終的にはMDインポータに関しては、あまり深くサポートしないことにした。自前で作ったMDインポータも配布はするが、インストールするかどうかはユーザーにまかせることにした。もっとも良い結末は、アップルがMIDI.mdimporterをアップグレードすることだ。もし、自前でMDインポータの開発を続けても、OS標準のMDインポータが強化されたら、努力が無駄になってしまうからね。&lt;/p&gt;</description>
			<pubDate>Thu, 20 Jan 2011 23:50:18 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/program/blog20110120.html</guid>
		</item>
		
		<item>
			<title>Quartzによるグラフィックの描画</title>
			<link>http://www.stripe-net.jp/cocoa/update/blog20101225.html</link>
			<category>サイト更新情報</category>
			<description>&lt;p&gt;久々にCocoaの記事を書きました。過去の記録を見ると、なんだか記事の更新が１年１回ペースになってますね（汗）&lt;br/&gt;&lt;br/&gt;で、今回の記事は&lt;a href=&quot;http://www.stripe-net.jp/cocoa/documents/chapter4/chapter4-1.html&quot;&gt;Quartzによるグラフィックの描画&lt;/a&gt;ということで、CocoaでNSViewの中にいろいろなグラフィックを描く事について書いています。&lt;br/&gt;この記事は約８年前にCocoa-Java向けに書いた記事のアップグレード見たいなもので、今回はグラフィックの描画だけにとどまらず、グラフィックの描画速度、描画パフォーマンスについて、&lt;code&gt;CFAbsoluteTimeGetCurrent()&lt;/code&gt;を使っていろいろ測定してみました。興味深い結果が出ています。&lt;br/&gt;また、最後にMacOSX10.6の新機能であるCPUのマルチコアを活かした、平行処理描画についてもやってみました。こちらは、Grand Central Dispatchの性能の良さが表れる結果が出ています。&lt;br/&gt;&lt;br/&gt;と、まあ今回の記事は後半が描画パフォーマンスの実験レポートのようになっています。&lt;br/&gt;実は私は工業高校の出身なんですが、かつては実験をしてはレポートを纏める毎日だったなぁ〜と、つい昔のことを思い出してしまいました。&lt;/p&gt;</description>
			<pubDate>Sat, 25 Dec 2010 13:21:29 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/update/blog20101225.html</guid>
		</item>
		
		<item>
			<title>MIDIWind2.1betaを公開</title>
			<link>http://www.stripe-net.jp/cocoa/software/blog20101122.html</link>
			<category>ソフトウエア</category>
			<description>&lt;p&gt;まったりと開発を進めていた&lt;a href=&quot;http://www.stripe-net.jp/cocoa/downloads/midiwind2.1.zip&quot;&gt;MIDIWind2.1&lt;/a&gt;がある程度形になってきたので、ベータ版として公開することにしました。&lt;br/&gt;&lt;/p&gt;&lt;img src=&quot;http://www.stripe-net.jp/cocoa/images/blog/blog20101122.png&quot; width=&quot;480&quot; height=&quot;287&quot;/&gt;&lt;p&gt;今回のバージョンでMacOSX10.6に対応するようになり、これでJavaのコードが全て削除されました。また、ユーザーインターフェースも大幅に修正しました。&lt;br/&gt;ただ、見ての通りまだまだ未実装な部分が多いので、完成までにはもう少しかかりそうです。&lt;/p&gt;</description>
			<pubDate>Mon, 22 Nov 2010 17:52:24 +0900</pubDate>
			<guid isPermaLink="true">http://www.stripe-net.jp/cocoa/software/blog20101122.html</guid>
		</item>
		
	</channel>
</rss>
