第3回 plist(プロパティリスト)とFoundation【前編】:Undocumented Mac OS X(4/4 ページ)
Mac OS Xにおいてオブジェクトの永続化に用いられるファイル形式plist。今回から2回にわたって、plistとこれに対応するFoundationフレームワークがMac OS Xをどのように支えているのか解説する。
plistとFoundation
plistの各要素は、Foundationと呼ばれるCocoaのフレームワークに存在するクラスと強く結びついている。plistの要素に対応するクラスが存在する上、plistの内容を格納したNSStringという文字列クラスに対しpropertyListというたった1つのメソッドを送るだけでplistの内容がパースされ、それぞれのクラスを用いたオブジェクトが生成、メモリに展開される。
ファイルからの入力
リスト4はその簡単なサンプルだ。NSStringクラスのインスタンスであるfilecontentには、filenameで指定されるファイルの内容がテキストとして丸ごと格納される(リスト4-1)。このfilecontentに対してpropertyListメッセージを送る(リスト4-2)と、その内容がパースされ、メモリ上に同等の構造をしたオブジェクト群がロードされる。
実行例2はリスト4の実行結果で、ここではリスト2のplistを読み込ませている。NSLog()関数*の出力からplistで表現されたのと同等のオブジェクトが生成されているのが分かる(図1)。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
実行に失敗した場合の対処
propertyListメソッドの実行に失敗した場合、例外が発生する(実行例3)。Objective-Cにおいて例外をとらえるには、NS_DURINGからNS_HANDLERで囲っておくと良い(リスト4-3)。例外発生時はNS_HANDLERからNS_ENDHANDLERまでの内容が実行される。また、例外の内容を示すオブジェクトはNS_HANDLERからNS_ENDHANLDERまでの間で有効な変数localExceptionに格納されている。このlocalExceptionの内容を確認することで、どこでパースエラーが起こっているのかが分かる*。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ファイルへの出力
ファイルへの出力を行うには、NSArrayもしくはNSDictionaryに対して「writeToFile:atomically:」メッセージを送ると良い。リスト5はそのサンプルだ。
リスト5の「@""」はソースコード中に埋めることのできるNSStringのリテラル*である。NSDictionaryは、生成時の構造からその内容を変更できないのに対し、そのサブクラスであるNSMutableDictionaryはその内容を変更可能という違いがある。ここでは、空のNSMutableDictionaryクラスのインスタンスを生成し、そこに順番にオブジェクトを格納していった後ファイル名を第1引数、真偽値のYES*を第2引数に「writeToFile:atomically:」メッセージを送付している。リスト6がその結果だ。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Key1</key>
<string>Value1</string>
<key>Key2</key>
<dict>
<key>SubKey1</key>
<string>Value2</string>
</dict>
<key>Key3</key>
<array>
<string>Member1</string>
<string>Member2</string>
<string>Member3</string>
</array>
</dict>
</plist>
このように、読み出しおよび書き込みに関しては簡単に処理される。Cocoaでは、データの格納、操作のために利用するNSStringやNSDictionaryといったオブジェクトは日常的に使われているため、わずか1つのメッセージを送るだけでファイルに保存し、オブジェクトを手軽に永続化できるのだ。
次回は
Foundationと同様に基本的なデータ構造を扱うフレームワークである「CoreFoundation」の紹介を交えつつ、「Mac OS Xの『魂』」であるFoundationとplistの理解を深めていきたい。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
このページで出てきた専門用語
NSLog()関数
NSLog()関数は、標準エラー出力に対して、第1引数で指定された書式で文字列を出力する手軽なデバッグ用の関数であり、「%@」という書式でObjective-Cのあらゆるオブジェクトを文字列に変換、出力を行う。なお、このとき出力先での文字化けを防ぐため、ASCII外の文字に関しては「\Uユニコード値」にエンコードされる。
パースエラーが起こっているのかが分かる
読み込むだけなら、NSDictionaryの「dictionaryWithContentsOfFile:」、ないしはNSArrayクラスの「arrayWithContentsOfFile:」メソッドを使えば1行で可能だが、これらはplistの文法が間違っていたとき単純にnilを返すだけで、エラーチェックが難しいという弱点がある。
NSStringのリテラル
GCCに含まれるObjective-Cコンパイラは「@""」からなる文字列をNSStringクラスのサブクラスである静的文字列クラスに展開する。この静的文字列クラスは、NeXTおよびGNUstepの古いバージョンではNXConstantStringクラスで、Mac OS XではNSConstantStringクラスになる。なお、「@""」の中にはASCII内の文字しか含めることができない。
YES
歴史的な事情から、YESは単に1の、NOは0に対するマクロであり、C++のtrue、falseのような真偽値ではない。
本記事は、オープンソースマガジン2006年1月号「Undocumented Mac OS X」を再構成したものです。
関連記事
- 連載第1回 initを置き換えるlaunchd【前編】
UNIX使いに真のMACPOWERを! 本連載では、UNIX使いに向け、UNIX系OSとしてのMac OS Xを解説していく。記念すべき第1回では、initに代わるものとしてMac OS X Tigerで採用された、launchdを紹介しよう。 - 連載第2回 initを置き換えるlaunchd【後編】
UNIX使いに真のMACPOWERを! 本連載では、UNIX使いに向け、UNIX系OSとしてのMac OS Xを解説していく。前回に引き続き、launchdの設定の詳細のほか、launchdの内部構造について踏み込んでいこう。
Copyright © ITmedia, Inc. All Rights Reserved.