6 | 9月 | 2012 | HMDT Blog

カテゴリー : 2012年 9月6日

mergeChangesFromContextDidSaveNotification:って何のために?


先日は、MOSAでCore Dataセミナーをやってきました。参加された方々、お疲れさまでした。

で、そのとき質問があって、NSManagedObjectContextのmergeChangesFromContextDidSaveNotification:に関する事だったんだけど、そのとき「このメソッド、あんまりよく分からないんだよねー」と答えてしまいました。そしたら、アンケートで「このことが聞きたかったのに残念だ」という意味のことを書かれてしまったので、ちょっとこの場でフォローします。

まず、前提。状況としては、複数スレッドからCore Dataにアクセスしている。スレッド毎にmanaged object contextを作成し、同一のpersistent store coordinatorを使う。

まず、サブスレッドを立てて、managed objectを追加したとする。そうすると、そのスレッドのmanaged object contextでは、追加される。でもこの追加は、メインスレッドのmanaged object contextからは検知されない。どうもオブジェクトの追加は、managed object contextレベルで行われているらしい。サブスレッドが終了すると、この追加もそのまま消えてしまう。

そこで、サブスレッドでオブジェクトを追加した後、保存を行う。そうすると、追加されたオブジェクトがデータベースに保存される。データベースに保存されるので、永続化される。この変更は、メインスレッドのmanaged object contextからも知る事ができる。保存後にフェッチすれば、追加されたオブジェクトを取得できる。

で、保存すると、NSManagedObjectContextDidSaveNotificationが通知される。それを捕まえて、Appleのドキュメントによれば、managed object contextのmergeChangesFromContextDidSaveNotification:を呼んでやれば、変更がマージされる、ということになっている。でもねー、保存した時点でデータベースに変更が反映されているんだから、マージする必要あんの?ってのが疑問としてあった。だから、「Appleのドキュメントに、このメソッドを呼べって書いてあるから呼ぶけどさー、これ別に呼ばなくても構わないんじゃないの?なんのためにやるのか、よく分かんないんだよねー」って思ってた。

そのときの質問は、mergeChangesFromContextDidSaveNotification:はメインスレッドで呼ぶ事になっているけど、そのときに時間がかかったりしないか、パフォーマンスは大丈夫か、というものだったんだけど、基本的には重い処理は保存のところなので、それは別スレッドで呼ばれるから大丈夫だと思う。

この、mergeChangesFromContextDidSaveNotification:を呼んだときの、別managed object contextのオブジェクトのマージって、どんなことが行われるんだろか。いまメモリ上に保持しているmanaged objctに限ってマージされる、ってことなのかな。であれば、リフェッチすれば、そもそも気にしなくていいのかな。