« rabbit のリポジトリから graphics/cairo を削除 | トップページ | MacPorts では ruby 関連のモジュールのインストールに RubyGems が使える »

2006.09.08

まわり道な方法で CoreData の属性の初期値を設定する

CoreData のモデルをコードから変更する 件の検証も兼ねて実験。

通常 CoreData で固定値以外の初期値を設定するには、NSManagedObject#awakeFromInsert を使うのが定石だ。ちなみに固定値は、NSAttributeDescription#defaultValue により設定されている。このへんは HMDT 3rd(赤) のChapter 7を読めば書いてある。

じゃあさ、NSAttributeDescription のサブクラスで defaultValue をオーバーライドしてやって、それをモデルが持つようにすればその defaultValue が呼ばれて好きな初期値が設定できるんじゃない?と考えた。ここで検証したいのは

  • NSAttributeDescription#defaultValue は毎回呼ばれるのか。NSManagedObjectContext にキャッシュされてればアウトだ。
  • コード上で本当に NSManagedObjectModel が変更できるか

の2点だな。

結論から先に言うと、両方とも問題なしだった。じゃ、今回の実験内容。

Objective-C だとめんどうなので、RubyCocoa でやった。

まずは、NSAttributeDescription のサブクラス

 class MyAttrDescription < OSX::NSAttributeDescription
   def defaultValue
     return OSX::NSDate.date
   end
 end

こんだけ。現在日時が初期値になるものだ。

次はドキュメント。これは NSPersistentDocument#managedObjectModel をオーバーライド。なんかぐだぐだだけど気にしない。

 class MyDocument < OSX::NSPersistentDocument
   # snip
   @@model = nil
     
   def managedObjectModel
     unless @@model
       @@model = super_managedObjectModel
       @@model.entities.each do |ent|
         # 元の属性の定義を削除
         attr_org = ent.attributesByName['createDate']
         props = ent.properties.mutableCopy
         props.removeObject(attr_org)
         # 新しい属性の定義を追加
         attr_new = MyAttrDescription.alloc.init
         attr_new.setName('createDate')
         attr_new.setAttributeType(OSX::NSDateAttributeType)
         props.addObject(attr_new)
 
         ent.setProperties(props)
       end
     end
     return @@model
   end
 
   # snip
 end

これで createDate という名前の属性は初期値が現在日時になる。今日の実験はこれまで。

|

« rabbit のリポジトリから graphics/cairo を削除 | トップページ | MacPorts では ruby 関連のモジュールのインストールに RubyGems が使える »