Macintosh Developer Online (MDOnline)


2001年5月8日発行号 - Cocoaの続き



先週のiWeekは、MDOnlineとして協賛しているということもあるのですが、加えて、AppleScript Users Groupで展示をしているということもあっての参加です。そのASUG割り当てのステージが初日の最初の方にあって、そのプレゼンテーションを、久々にやるということもあって(笑)、ちょっとはりきりっていたのですが、いろいろ変なところに凝っていたため、はまったというところです。それでも、QuickTime 5のスクリプトはかなりマスターしたのではないかと思います。もちろん、AppleScriptのデモやらOMEのデモなんかをしましたけど、裏でもAppleScriptでムービーのコントロールをしているというマニアックなことをしてしまったという次第です。
それで、iWeekの会場でPowerLabさんが展示および販売をされていたのですが、PowerBookの256MBのメモリが1万円だったので、思わず買ってしまいました。384MBになりました。64MBのメモリが余ってしまったけど…。後で調べたらかなり破格値だったようで、得をした気分です。もちろん、Mac OS Xを安定して動かすためです。当然ながら、ディスクアクセスの頻度はかなり少なくなり、静かにPowerBookは動いています。だけど、仮想記憶で利用するページングファイルは少なくなるということはないようです。また、通常のレスポンスもほとんど変わらない感じです。たまにディスクアクセスで応答が無くなるのが減ったとか、アプリケーションの切り替えなどではスムーズになったというところでしょうか。やっぱり起動時はページングファイルを作るとなると、大きな改善はないのかもしれません。それでも、ディスクにアクセスしっぱなしになることはほとんどない点は、全体的に見てもやっぱり安定するというところでしょうか。メモリを多く搭載するメリットはあるけど、その場合でもハードディスクの空き容量の確保は必要ということのようです。
(新居雅行 msyk@mdonline.jp


今から始めるCocoaプログラミング》ドラッグ&ドロップでファイルを開く(3)ダブルクリック起動と区別

Cocoaアプリケーションで、Finderからのドラッグ&ドロップを受け付ける方法を解説する続きをお届けしよう。まずは簡単に復習したいが、1回目はDelegateという概念を説明した。あるオブジェクトでの処理を別のオブジェクトにまかせるという考え方であり、Cocoaのフレームワークではいろいろなクラスでこの手法を使っている。アプリケーションであるNSApplicationでもこのDelegeteを使っている。また、何かが起こったときには、Notificationというメカニズムで通知が行われるが、その通知の受け取りオブジェクトもDelegeteで別のオブジェクトに振り分けることができる。従って、独自にプログラムしたクラスに対して、アプリケーション(File’s Owner)からDelegeteしておくことで、自分のプログラム側で、アプリケーション内に発生したイベントやNotificationに対応する処理ができるというわけである。こうした対応付けは、Interface Builderで行うことができる。
Finderでアプリケーションに対して文書ファイルをドラッグ&ドロップした場合や、あるいはDock上のアプリケーションアイコンにドラッグ&ドロップした場合、NSApplicationではapplicationOpenFileというメソッドが呼び出される。しかしながら、別のオブジェクトにDelegateしておくと、そのオブジェクトのapplicationOpenFileメソッドが呼び出される。だから、自分で定義したクラスにapplicationOpenFileメソッドを記述すれば、ドラッグ&ドロップしたファイルを処理するプログラムが書けるということになる。前回までに説明したことの趣旨は以上の通りだ。

では次の課題に入りたいが、ちょっとしたツール的なアプリケーションを作りたいとしよう。ファイルをドラッグ&ドロップしてきたときの処理はapplicationOpenFileメソッドに書くとして、単にダブルクリックしたときと別の処理に切り分けたいとする。そのときに使える手法が、NSApplicationクラスに定義されたNotificationである。Notificationは、メカニズム的にはNotificationCenterというところからオブジェクトに対して送信されるものであり、ある状況で送信されるように設定などを行うのが通常である。だけども、NSApplicationにあるNotificationはそうした基本的な設定は全部クラスの中でやってくれる。使う側としては、単にある状況で決められた名前のメソッドが呼び出されるという事実だけを使えばいいので、Notificationについての詳しい説明は割愛させていただく。
具体的には、NSApplicationからDelegateされたオブジェクト(これまでのサンプルではDocOpenHanlderクラスのインスタンス)に対して、アプリケーションの起動処理をする前と、起動処理を終了したときにNotificationが発生する。つまり、そのタイミングで、Delegateされたオブジェクトの規定のメソッドが呼び出されるのである。アプリケーションの起動前はapplicationWillFinishLaunching、起動後はapplicationDidFinishLaunchingというメソッドが呼び出される。もちろん、定義に従って引数などを記述しなければならないが、具体的には次のように、DocOpenHanlder.javaの中身を記述する。Delegationの動作を見るだけなので、まずは標準出力にテキストだけを書き出してみよう。


/* DocOpenHanlder */

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

public class DocOpenHanlder extends NSObject {

public boolean applicationOpenFile(
NSApplication theApplication,
String filename) {
System.out.println("applicationOpenFile:"+filename);
return true;
}
public void applicationWillFinishLaunching(
NSNotification aNotification) {
System.out.println("applicationWillFinishLaunching:");
}
public void applicationDidFinishLaunching(
NSNotification aNotification) {
System.out.println("applicationDidFinishLaunching:");
}
}

applicationWillFinishLaunchingおよびapplicationDidFinishLaunchingは、いずれも戻り値はなく、引数はNSNotificationクラスのものが1つあるだけだ。
こうしてビルドしたアプリケーションをそのまま単に起動するとしよう。たとえば、Project Builderで起動すると、コンソール出力には、次のように表示されるはずだ。つまり、それぞれのメソッドが順番通りに呼び出されたことになる。

applicationWillFinishLaunching:
applicationDidFinishLaunching:

では、次にビルドしたアプリケーションに対して、Finder上でファイルをドラッグ&ドロップして、アプリケーションを起動してみよう。プロジェクトがテンプレートから作成されたままなら、ドラッグ&ドロップしても反応しないかもしれないが、その場合はCommand+optionを押しながらドラッグ&ドロップすればよい。そして、/Applications/UtilitiesにあるConsoleというアプリケーションで、標準出力の結果を参照するとよいだろう。次のようになっている。

applicationWillFinishLaunching:
applicationOpenFile:/Users/msyk/Pictures/Shot0007.pict
applicationDidFinishLaunching:

つまり、アプリケーションが起動するときには、まずapplicationWillFinishLaunchingが呼び出される。そしてドラッグ&ドロップしたファイルを処理するためにapplicationOpenFileが呼び出される。そして、最後にapplicationDidFinishLaunchingが呼び出されるという順序になるわけだ。
ならば、インスタンス変数を適当に定義して、applicationOpenFileメソッドを通過したかどうかを判断できるようにしておき、通過していない場合には、applicationDidFinishLaunchingで単に起動した場合の処理を呼び出せばよいということになる。プログラムとしては以下のようにDocOpenHanlder.javaで記述すればよいだろう。変数isOpenDocumentは、applicationOpenFileを通過したかどうかを判断する変数だ。もし、単にアプリケーションがダブルクリックされて起動されたのなら、メソッドbootByDoubleClickが呼び出されるという風にしてみた。

/* DocOpenHanlder */

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;

public class DocOpenHanlder extends NSObject {
private boolean isOpenDocument = false;

public boolean applicationOpenFile(
NSApplication theApplication,
String filename) {
System.out.println("applicationOpenFile:"+filename);
isOpenDocument = true;
return true;
}
public void applicationWillFinishLaunching(
NSNotification aNotification) {
System.out.println("applicationWillFinishLaunching:");
}
public void applicationDidFinishLaunching(
NSNotification aNotification) {
System.out.println("applicationDidFinishLaunching:");
if(! isOpenDocument)
bootByDoubleClick();
NSApplication thisApp = (NSApplication)aNotification.object();
thisApp.terminate(this);
}

private void bootByDoubleClick() {
System.out.println("bootByDoubleClick:");
}
}

ここで、applicationDidFinishLaunchingメソッドを見てもらいたい、状況に応じてbootByDoubleClickを呼び出すが、その後に、起動したアプリケーションを終了する処理を組み込んでいる。applicationWillFinishLaunchingやapplicationDidFinishLaunchingといった、NSApplicationクラスでのNotificationによって呼び出されるメソッドは、引数のNSNotificationオブジェクトのobjectメソッドで取り出されるのは、アプリケーションそのものへの参照になる。objectメソッドの戻り値はNSObjectなのでNSApplication型にキャストする。そして、アプリケーションではterminateメソッドを適用すれば、そのアプリケーションを終了させることができるのである。必ずしも終了させないといけないというわけではないが、NSNotification型で得られた引数の使い方を説明する一例として参照してもらいたい。

以上のように、Delegateという仕組みで、アプリケーションの機能をある意味では拡張できる。しかしながら、サブクラスといった手法ではなく、新たなクラスで単に必要なメソッドだけを用意してやればいいというだけのことなので、やり方は非常にシンプルなものとなっている。今回の一連の記事では、3つのメソッドだけを示したが、実はかなりたくさんのDelegate対応メソッドがある。NSApplicationのドキュメントを参照していただきたい。

カテゴリ:Cocoa, 今から始めるCocoaプログラミング


QuickDNS 3.5はBINDをGUIツールでリモート管理、Mac OS XやLinuxに対応

Mac OSで稼働するDNSサーバとして知られるQuickDNSがバージョンアップしてVer.3.5となった。Mac OSでは、サーバと管理ツールが一体化したDNSシステムであった。しかしながら、Ver.3.5はMac OS Xや各種のLinuxディストリビューションに対応し、製品の形態も変更された。これらUNIXベースのOSでは、BINDというDNSサーバが一般的に使われている。QuickDNS 3.5ではDNSサーバ機能はBINDを使い、サーバ上でQuickDNS Remoteを稼働させ、クライアントからの管理要求に対応できるようにする。そして、クライアントでは、QuickDNS Managerを利用し、グラフィカルユーザインタフェースを持った管理ツールでDNSサーバを管理できるようになっている。QuickDNS Managerは、Mac OS 8/9/XあるいはWindowsで利用できるようになっている。QuickDNSは、DNSサーバというよりも、「DNSサーバ管理ツール」と呼ぶ方がふさわしいだろう。BIND 8.2.3が稼働している環境を前提としている。BINDの設定はいくつかのテキストファイルを使って行うが、設定を行うことはもちろん、変更が時折発生するとなると、毎度テキストファイルの記述変更を行うなどそのままでは管理手間は大きい。QuickDNSを利用すれば、設定を簡単に行うという点に加えて、プロバイダなどで多くのサーバを管理したり、あるいはサーバの設定が頻繁にあるような現場ではかなり重宝するだろう。その点では、Linux対応という点も注目に値する機能だ。シングルライセンスが$349、2ライセンスが$549となっている。

関連リンク:Men and Mice
カテゴリ:その他のインターネット, ネットワーク


TIL》iBookではPowerBook G4のACアダプタが使えるが、注意も必要

2001年5月に発表されたDual USBタイプのiBookは、PowerBook G4のACアダプタが使えることがTech Info Libraryに掲載された。いずれの機種のアダプタも、電気的な特性は同一なので、iBookでもPowerBook G4のACアダプタは使える。ただし、PowerBook G4のアダプタのプラグには突起がある。iBookに接続したときその突起は向きによっては、ドライブの取り出しを阻止することもあるので、突起をドライブのトレイの正面に来ないような位置で使う必要がある。

関連リンク:iBook (Dual USB): Using PowerBook G4 Adapter
カテゴリ:Knowledge Base(旧TIL), iBook


TIL》新しいiBookに組み込まれたキーボードの前の機種との違い

2001年5月に発表されたDual USBタイプのiBookのキーボードに関する文書がTech Info Libraryに掲載された。キーボードについての、前の機種からの変更点がまとめられており、ミュートがF3キーに移動したことや、Commandキーがスペースキーの両側にあるようになったことなどが解説されている。ただし、キーボードは米国向けの機種のもので説明されている。

関連リンク:iBook (Dual USB): Keyboard Layout
カテゴリ:Knowledge Base(旧TIL), iBook


NSToolbarにカスタムビューを持つアイテムを追加した場合にはサイズを設定する

Technical Q&Aに、Cocoaでのツールバーの利用方法に関する文書が掲載された。NSToolbarItemを作成しカスタムビューを-setViewで追加したが、ツールバーにはカスタムビューが見えない。しかしながら、ウインドウにツールバーを追加したら見えるようになるという質問である。NSToolbarItemsの高さと幅の最大値と最小値は、いずれも0になっている。-setImageを使うと画像のサイズに合わせられるが、-setViewではサイズはそのままになる。従って、カスタムビューは見えないということになる。-setMinSize、-setMaxSizeメソッドを呼び出し、適切なサイズに設定をすればよい。

関連リンク:QA1029:How to get custom views to show up in NSToolbarItems
カテゴリ:Technical Q&A, Cocoa


Interface BuilderでNSWindowの特定のActionが利用できないのはバグ

Technical Q&Aに、Interface Builderでツールバーの表示や非表示の機能が働かない点についての文書が掲載された。ツールバーを隠すというメニューを選択した場合にFirst Responderの-toggleToolbarShown:を呼び出したり、ツールバーのカスタマイズのメニューを選択したときに-runToolbarCustomizationPalette:を呼び出したいのであるが、それがInterface Builderで一覧に出てこないというものである。これらのActionはNSWindowに確かに組み込まれているけど、Interface Builderで見えないのはバグである。手作業で、Interface Builderで見えているFirst ResponderのクラスにActionを定義することで、メニュー項目とActionの関連づけはできるようになる。

関連リンク:QA1030:Getting NSWindow’s toolbar actions to show up in Interface Builder
カテゴリ:Technical Q&A, ProjectBuilder/Interface Builder, Cocoa


特定のアプリケーションにだけデバッグ用のCarbonLibを適用する方法

CarbonLibの代わりにDebuggingCarbonLibを機能拡張フォルダに入れて再起動すると、アサートの表示ができるようになるが、デバッグしているアプリケーションだけのアサートを得られるようにできるかどうかという質問に対する答えがTechnical Q&Aに掲載された。通常のCarbonLibで起動し、DebuggingCarbonLibのファイルタイプをshlbに変更してアプリケーションと同じフォルダに入れておく。そうすれば、Code Fragment Managerは機能拡張フォルダにあるCarbonLibではなく、アプリケーションと同じフォルダにあるDebuggingCarbonLibをロードして利用するようになる。そうすれば特定のアプリケーションだけデバッグ用のCarbonLibを利用できる。ただし、CarbonLibのバージョンがシステムフォルダのものと同一である必要がある。

関連リンク:QA1033:Targeting DebuggingCarbonLib asserts
カテゴリ:Technical Q&A, Carbon/CF


デバッガのgdbでMacsBugのコマンドを使う機能を有効にする方法

Mac OS XのDeveloper Toolsをインストールすると、デバッガのgdbを、従来のMac OSで動いていたデバッガのMacsBugと同じように使えるようにするセットもインストールされている。この利用方法についての文書がTechnical Q&Aに掲載されている。/usr/libexec/gdb/plugins/MacsBugというディレクトリ階層に、必要なファイルや設定方法などを記載した文書が存在するのでそれを参照すれば利用できるとしている。ただし、利用方法についての説明に間違いがある。それに関する情報がこの文書に記載されているので、gdbのMacsBugプラグインを使う場合には、この文書を読んでから、インストールされた利用方法と付き合わせて、設定を行う必要がある。

関連リンク:QA1032:Late breaking news for the MacsBug gdb plugin
カテゴリ:Technical Q&A, 開発情報


TIL》Power Mac G4でApple CUP Pluginがインストールできない場合

Gigabit Ethernetで、Dual CPUタイプのPower Mac G4では、起動ディスク以外にMac OS Xをインストールしたディスクがあると、Apple CPU PluginのインストールができなくなるということがTech Info Libraryに掲載されている。Mac OS Xをインストールしたディスクをゴミ箱に捨ててマウントと解除して作業をすればよいと記載されている。

関連リンク:Power Mac G4 (Gigabit Ethernet): Installing Apple CPU Plugin with Mac OS X on Additional Disk
カテゴリ:Knowledge Base(旧TIL), Power Mac


TIL》AppleWorksでのWeb経由のクリップ集を使う時のキャッシュ容量

Tech Info Libraryに、AppleWorksで使うクリップ集のキャッシュサイズを変更する方法が掲載されている。Web経由でクリップ集をダウンロードするのにキャッシュが使われるが、たとえばMacintosh Managerを使っている場合にはディスク使用量の増加を防ぎたいためにキャッシュのサイズを0にするということもできる。クリップ集のウインドウをcontrolキーを押しながらクリックして、「クリップ集の設定」を選択すると、設定が可能となっている。

関連リンク:AppleWorks 6: How to Set the Clippings Cache Size
カテゴリ:Knowledge Base(旧TIL), 文書作成アプリケーション