Re: Strange NSManagedObjectContextObjectsDidChangeNotification behavior
Re: Strange NSManagedObjectContextObjectsDidChangeNotification behavior
- Subject: Re: Strange NSManagedObjectContextObjectsDidChangeNotification behavior
- From: Dave Fernandes <email@hidden>
- Date: Tue, 24 Feb 2009 23:02:58 -0500
On Feb 24, 2009, at 6:41 PM, Jerry Krinock wrote:
But, just a warning. I originally had this grand plan which may be
similar to yours -- I was going to simply observe
NSManagedObjectContextObjectsDidChangeNotification, decode whatever
happened as I just advised you to do, and then implement all my
business logic in that observer. But it got to be more and more
painful. The deal-breaker was last week when I learned that -
[NSManagedObject changedValues] continues to include changed keys
that had already been noted in previous notifications, until the
document is saved. So I would decode the same change repeatedly.
With that discovery, I decided to bite the bullet and use KVO for
most of the changes instead of
NSManagedObjectContextObjectsDidChangeNotification.
I can't say I have the ideal solution, and I am also using KVO, but
one might want to heed Ben Trumbull's warning before going down this
path...
Complex KVO observer actions need to be carefully constrained. If
they simply grow organically, then it's pretty easy to fall into
the trap of observers creating side effects that trigger other
observers that cascade to yet more observers. This (a) makes
your code impossible to understand, since no one ever
intentionally designed their app that way from the beginning, and
(b) sucks for performance.
It's often easier to understand, and much faster, to use
NSNotificationCenter to defer and coalesce observations for a
batch operation like operating upon 2000 objects. One way to
achieve this with the array controller is to remove all the
objects from the controller, do your batch operation, and then
add them back
It turned out to be not so bad, after I invented (or maybe re-
invented -- someone will correct me) a little idea which I call
"class observers", implemented it in my NSManagedObject subclass,
and made all my managed object classes a subclass of this. Each
subsubclass (i.e. Employee, Recipe, whatever) overrides
+classObservers, providing a dictionary of "observer dictionaries",
each one giving a keyPath, observer, options and context. Whenever
an instance object of this subsubclass is created, it has all these
"class observers" set automatically (during -awakeFromInsert or -
awakeFromFetch), and whenever it's destroyed (-didBecomeFault in
Core-Data-speak), these observers are removed. So I'm not afraid
of forgetting to remove observers any more. Let me know if you
want the code for this.
I'm only just getting familiar with the idiosyncrasies of Leopard,
however, in Tiger didBecomeFault might be called many times, but
awakeFromInsert or awakeFromFetch was only called once for the
lifetime of the MOC (not the lifetime of the object). Thus, if you
delete the object, and then undo that action, your observers will be
removed by didBecomeFault and not added back since awakeFromFetch is
not called again.
Dave
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden