Re: willChangeValueForKey, Ivars and Core Data
Re: willChangeValueForKey, Ivars and Core Data
- Subject: Re: willChangeValueForKey, Ivars and Core Data
- From: Scott Ahten <email@hidden>
- Date: Mon, 19 Sep 2005 23:05:25 -0400
On Sep 19, 2005, at 7:48 AM, Jim Correia wrote:
On Sep 19, 2005, at 1:14 AM, Scott Ahten wrote:
A NSTimer is used to calculate and update this value every second,
which is displayed in a NSTableView column in my UI using KVO.
However, when this attribute is set, a dark dot is displayed in
the close button and the document is flagged as "dirty". Since
this attribute is set to transient in my CoreData model, not used
to set other persistent properties, nor are any persistent
attributes "dependent" on this attribute, I'm not sure why the
document thinks it's dirty and needs to be saved.
How would CoreData know whether or not your transient attribute has
any persistent attributes derived from it? (This information cannot
be expressed in the model.)
By "dependent" I mean that none of my CoreData persistent properties
are dependent on my iVar by triggering change notifications for
persistent attributes in KVO when calling....
NSArray *keys = [NSArray arrayWithObjects:@"timeInHMS", nil];
[self setKeys:keys
triggerChangeNotificationsForDependentKey:@"aPersistentAttribute "];
In my objects initialize method.
If CoreData didn't mark the object dirty when a transient attribute
changed, the delayed-update set accessor pattern for non-standard
attribues wouldn't work.
<http://developer.apple.com/documentation/Cocoa/Conceptual/CoreData/
Articles/cdNSAttributes.html>
In other cases, it can be a nuisance that changing a transient
attribute marks the object dirty. In this situation I've
reconsidered my use of transient attributes on a case by case basis
to see if that is really what I needed, or if a plain old iVar
would better suit my needs.
In this case, an iVar is seems like the best solution since this
property is set very often, does not need to be undone and is not
used for non-standard attributes.
In an attempt to resolve this issue, I've created a ivar for the
attribute in my NSMangedObject subclass and manage it's storage
myself. After creating my own accessor methods, setting this value
no longer marks my document as dirty, but the table column is not
notified of the change. Wrapping the assignment in my accessor
with willChangeValueForKey: and didChangeValueForKey: calls
updates the table
That is correct. Automatic key value observing is turned off for
subclasses of NSManagedObject. You need to re-enable it per key for
plain old iVars, or manually invoke will/didChangeValueForKey.
but marks the document as dirty even though this value is no
longer and attribute of my CoreData model and I'm managing my own
storage.
[...]
How do I avoid setting my document as dirty yet notify any objects
observing this value that it has changed?
I don't have a standalone example which currently does this. Have
you set a breakpoint to see who is marking the document dirty?
Setting a breakpoint on didChangeValueForKey runs into the depths of
NSManagedObject, which is difficult to interpret. The document never
seems to become dirty until the method call is complete.
However, after implementing a custom version of - (void)
updateChangeCount:(NSDocumentChangeType)changeType for my document,
It appears that [NSUndoManager endUndoGrouping] is posting a
notification though NSNotifiationCenter, which is calling
updateChangeCount on my document. What's odd is that this
notification is only sent after I call will/didChangeValueForKey
*and* click on my application or attempt to save using CMD+S. If I do
not interact with my application, the notification is not immediately
posted after will/did is actually called though the thread from NSTimer.
What's unique about this class is that it uses an static instance of
NSTimer to call one of it's own class methods. This method sends a
refresh message to an array of "active" instances it maintains, which
calculates a value for the instance and sets it's own iVar using an
accessor. Calling will/didChangeValueForKey in the accessor sends a
change notification to the UI, but also flags the document as dirty.
- Scott
- - -
:: email@hidden
:: http://www.pixelfreak.net
- - -
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden