Lissajousエンティティを作る【実践的Macintoshプログラミング解説】

印刷用表示 |テキストサイズ 小 |中 |大 |

CoreData版 Repeating Motif Generator の開発 Repeating Motif Wonderland CoreData 実践的 Macintosh プログラミング解説

LinkIconホーム

更新日 2009-05-24

モデルを作る

Lissajousエンティティを作る

LissajousEntityPicture.png 第一のプロジェクトと同様に、エンティティの設計から始めます。

 リサージュ図形は二つの発振器出力を組み合わせて作ります。したがってLissajousエンティティは二つのOscillatorエンティティを所有する事になります。また、これに伴って逆関連を設定する必要が出てくる為に、Oscillatorエンティティにも変更が必要になります。

 LissajousエンティティとOscillatorエンティティにはベジエパスを持つという共通点があります。そこで両者の親エンティティPathHolderを作成します。

 完成したエンティティは、Xcodeのモデルエディタで右の様に表示されます。

PathHolderエンティティとLissajousエンティティを追加する

LissajousEntityList.png モデルエディタのエンティティパネル左下のプラスボタンをクリックして、エンティティを追加します。エンティティ名をLissajous、クラス名もLissajousとします。
 旧バージョンにLissajousというクラスはありませんのでLissajousCDとする必要はありません。

 そしてもう一つのエンティティPathHolderを追加します。こちらは「抽象」チェックボックスにチェックを入れておきます。

 PathHolderの親エンティティをRMGRoot、LissajousとOscillatorの親エンティティをPathHolderにそれぞれ変更します。

PathHolderEntityPanel.pngLissajousEntityPanel.pngOscillatorEntityPanel.png

RMGRootの属性

order

  •  リサージュ図形はX軸の発振器とY軸の発振器の出力を組み合わせて作られます。例えばX軸の発振器のパラメータを設定したいといったように、特定のOscillatorにアクセスしたい場合が考えられるので、特定のOscillatorへのアクセサメソッドが必要です。 
  •  したがってOscillatorを特定する必要があるのですが、そのために順番を表す属性orderを追加します。対多関連が順序情報を持っていればよかったのですが、残念ながら対多関連はNSArrayではなくNSSetなので順序情報を持っていません。そこでエンティティが順序情報を持つ必要があるというわけです。
  • …というつもりで追加した属性でした。ところがorderでOscillatorを特定するとKey Value Observingが破綻するようで、うまく動きませんでした。 しかたがないのでOscillatorを特定する関連を追加する事にしました。
  •  したがってorder属性は当面役には立たないのですが、順序情報はテーブルビューで並び順を決める時にいずれ使う事になると思いますので、残しておく事にします。
  •  下の図の様に設定します。
RMGRootProperty.pngorderProperty2.png

PathHolderの属性

bezierPath

  •  Oscillatorの場合は出力波形、Lissajousの場合はリサージュ図形を表すパスです。これはファイルに保存しませんが、アンドゥには対応する必要があります。したがってPathHolderエンティティの属性とすべきです。ただし「一時」にチェックを入れてファイルに保存されない様にします。

属性を追加する

 上で決めた様にPathHolderエンティティに属性を追加します。 プロパティパネル左下のプラスボタンをクリックして属性を追加していくと、最終的に下の図の様になります。

 各属性の詳細設定は以下の様にしました。

PathHolderProperty.pngbezierPathProperty.png

Lissajousの属性

resolution

  •  発振器出力の波形をどの程度細かくするのかを決めるパラメータです。一周期を何分割するのかを表す数で、大きければそれだけ滑らかになりますがデータとしては重くなります。
  •  これはリサージュ図形のパラメータであり、ファイルに保存する必要があるのでLissajoursエンティティの属性とすべきです。

oscillators

  •  リサージュ図形はX軸の発振器とY軸の発振器が出力する波形によって決定されます。したがってLissajoursエンティティに二つのOscillatorエンティティを所有させます。
  •  oscillatorsは属性ではなく関連です。対多関連なので名前を複数形にしました。

x, y

  •  X軸の発振器とY軸の発振器を特定する為の関連です。

属性を追加する

LissajousProperty.png 上で決めた様にLissajousエンティティに属性を追加します。 プロパティパネル左下のプラスボタンをクリックして属性を追加していくと、最終的に右の様になります。

 各属性の詳細設定は以下の様にしました。

 oscillators関連の削除ルールをカスケードにしています。これにより、Lissajousを削除するとoscillators関連に結びつけられているOscillatorが削除される様になります。

 x, yの関連はOscillatorを特定する為のものですので、削除ルールを使いません。したがって逆関連もなしです。

oscillatorsProperty2.pngresolutionProperty2.png
xRelation.pngyRelation.png

Oscillatorエンティティに関連を追加する

 上の図ではLissajousエンティティのoscillators関連で、逆関連を設定していますが、これはOscillatorsエンティティにlissajous関連を追加しないと設定できません。そこでこの関連を追加します。

 waveform属性は親エンティティであるPathHolderのbezierPath属性を使うため不要になりましたので削除します。

OscillatorProperty2.png

LissajousRelation.png

ソースコードを生成する

 RMGDocument.xcdatamodelを選択してモデルエディタを起動した状態で、Xcodeのファイルメニューから「新規ファイル…」を実行します。するとリストの最後に「管理オブジェクトクラス」が存在するので、これを選択して次へ進みます。

  • RMGDocument.xcdatamodelを選択していないと「管理オブジェクトクラス」が現れないので注意!

newFileAssistant.png

 次のページは変更する必要がないので、何もいじらずに次に進みます。

newFileAssistant2.png

 すると最後にエンティティを選択できるので、LissajousエンティティとPathHolderエンティティを選択します。下に三つのチェックボックスがありますが「アクセサを生成」だけをチェックしておきます。
 Obj-C 2.0を使うとTigerをサポートできなくなるので、ここでは選択しません。
 検証メソッドは実装を省略します。

newFileLissajous.png

生成されたインターフェイスファイル

 「新規ファイル…」を実行して生成されたPathHolder.hは以下の様になりました。

 各プロパティに対応するアクセサメソッドの宣言が並んでいます。インスタンス変数は何もありません。

//
//  PathHolder.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "RMGRoot.h"


@interface PathHolder :  RMGRoot  
{
}

- (UNKNOWN_TYPE)bezierPath;
- (void)setBezierPath:(UNKNOWN_TYPE)value;

@end

 「新規ファイル…」を実行して生成されたLissajous.hは以下の様になりました。

 各プロパティに対応するアクセサメソッドの宣言が並んでいます。インスタンス変数は何もありません。

//
//  Lissajous.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "PathHolder.h"

@class OscillatorCD;

@interface Lissajous :  PathHolder  
{
}

- (NSNumber *)resolution;
- (void)setResolution:(NSNumber *)value;

- (OscillatorCD *)x;
- (void)setX:(OscillatorCD *)value;

- (OscillatorCD *)y;
- (void)setY:(OscillatorCD *)value;

// Access to-many relationship via -[NSObject mutableSetValueForKey:]
- (void)addOscillatorsObject:(OscillatorCD *)value;
- (void)removeOscillatorsObject:(OscillatorCD *)value;

@end

UNKOWN_TYPEを修正する

bezierPathProperty.png bezierPath属性のデータ型は「未定義」です。これのアクセサメソッドはUNKNOWN_TYPEというクラス名で生成されました。このままではコンパイル時にエラーになりますので、修正します。

 bezierPathはNSBezierPathクラスのオブジェクトです。そこでUNKNOWN_TYPEをNSBezierPath *に置き換えます。 

 インターフェイスファイルの修正は以上です。修正後はこうなります。

//
//  PathHolder.h
//  RepeatingMotifGenerator
//
//  Copyright 2008 NovemberKou. All rights reserved.
//

#import <CoreData/CoreData.h>
#import "RMGRoot.h"


@interface PathHolder :  RMGRoot  
{
}

- (NSBezierPath *)bezierPath;
- (void)setBezierPath:(NSBezierPath *)value;

@end