CoreDataのお勉強

2006年6月3日土曜日

Happy Macintosh Developing Time Third Edition Cocoaプログラマのための技術解説書

著者:木下 誠

発売日:2006/05

価格: ¥ 3,990

ISBN: 4861003806




日本初のCoreData詳細解説を含むという上の図書が発行されたので、さっそくCoreData部分を読んでます。前に見た解説書では、エンティティとプロパティを作って、nibにドラッグアンドドロップで簡単に入力画面までできる!とだけしか書いておらず、それじゃーデータをいじりたいとき(たとえば小計の欄を足したい)とかはどうすりゃいいの?と思ってたんですよね。

手探りですが、すこーし分かったような気がします。p.282のiTunes Music Libraryを読み込むimportメソッドを、RubyCocoaバージョンにしてみました。



def import
path = "/Users/[ユーザ名]/Music/iTunes/iTunes Music Library.xml"
dict = OSX::NSDictionary.dictionaryWithContentsOfFile(path)
if (dict==nil)
return
end

entity = OSX::NSEntityDescription.entityForName("Track", :inManagedObjectContext, @managedObjectContext)

                   @managedObjectContext.undoManager.disableUndoRegistration

request = OSX::NSFetchRequest.alloc.init
request.setEntity(entity)

managedTracks = @managedObjectContext.executeFetchRequest(request, :error, nil)
enum = managedTracks.objectEnumerator.to_a
for i in 0..enum.length - 1
@managedObjectContext.deleteObject(enum[i])
end

#request.release
#requestのリリースは不要(禁止)

tracks = dict.objectForKey("Tracks")
enumerator = tracks.keyEnumerator
key = enumerator.to_a

for i in 0..key.length - 1
track = tracks.objectForKey(key[i])
trackObject = OSX::NSEntityDescription.insertNewObjectForEntityForName("Track", :inManagedObjectContext, @managedObjectContext)

title = track.objectForKey("Name")
trackObject.setValue(title, :forKey, "title") if title

album = track.objectForKey("Album")
trackObject.setValue(album, :forKey, "album") if album

artist = track.objectForKey("Artist")
trackObject.setValue(artist, :forKey, "artist") if artist

year = track.objectForKey("Year")
trackObject.setValue(year, :forKey, "year") if year

end

@managedObjectContext.processPendingChanges
@managedObjectContext.enableUndoRegistration

end



ちょっとはまったのが、NSEntityDescription。仕様書みてもそれをどうRubyで書けばいいかわかんなくて、ググりまくり。またNSFetchRequestって、rubyではrelaseしなくていいのかな。releaseしちゃうと1回目は問題ないのですが、もう一度importボタンを押すと、デバッガが立ち上がって、なにやら暗号をはき出してくれるのでした。コメントアウトしたら起きなくなったから、おそらくこの所為だなあと思って。NSDictionaryをhashにできる、とRubyCocoaの説明に書いてあったので、今度はそれを手さぐりしてみます。

ついでにBindingも学ぼうと思ったら、Bindingは前版を見てくれと「はじめに」に書いてありました。orz これって3rd ed.とかなってるけど、実はv. 3だったのでした。また、初めてCocoa使うんだけど、という人には向いてないですね。1から説明してくれてるわけじゃないので。

6 コメント:

  • RubyCocoaではreleaseは必要ないです。というか、原則禁止。
    ガベージコレクタがてきとうなタイミングでreleaseします。
    そのへんもドキュメントちゃんと書かなくちゃですね。お手数おかけします。

  • やはり!
    どこかでRubyCocoaではオブジェクトのリリースは気にしなくて良いとか書かれてたように思ったので、あてずっぽうでrelease行をコメントアウトしたのでした。

  • 書き忘れちゃいましたが、retainも原則禁止です。
    メモリ管理まわりは、ふつうのrubyプログラムと同じように
    気にしないで書けばよいようになっています。

  • ありがとうございます。
    ということは、undoManagerの部分も要らないってことでしょうか。
    確かに削っても問題なさそう。。。

  • アンドゥマネージャはCocoaのretain/releaseとは別にCoreDataの中でのデータストアの仕組みなので、そこは必要かと。
    ただ、ここのサンプルでは、アンドゥを無効にすることで、戻すためのデータを保持しない(パフォーマンスを上げる)ようにしているんだと思います。なので、コメントアウトしても動作はすると思います。
    ちょっと遅くなるかもしれませんが。
    アンドゥマネージャの役割は、赤本のP.360あたりに少うし書いてあります。

  • >ちょっと遅くなるかもしれませんが。
    >アンドゥマネージャの役割は、赤本のP.360あたりに少うし書いてあります。
    なるほど!この「遅くなるから」が一番難しい(やらなくても動いてしまうので、理解してないとなぜあるのか分からない)部分なんです。すっきりしました。

  • コメントを投稿