• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Core Data: Changing Transient Keys Dirties Database?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Core Data: Changing Transient Keys Dirties Database?


  • Subject: Re: Core Data: Changing Transient Keys Dirties Database?
  • From: mmalcolm crawford <email@hidden>
  • Date: Sat, 25 Jun 2005 02:11:08 -0700


On Jun 22, 2005, at 1:26 PM, Robert McNally wrote:
The point of a transient property is precisely that, although it's not stored in the persistent store, Core Data does track changes and register undo events for the property...
<http://developer.apple.com/documentation/Cocoa/Reference/ CoreData_ObjC/Classes/NSPropertyDescription.html#//apple_ref/doc/ uid/TP30001178-BAJHJGHJ>

That's fine, but the document you refer to says "Transient properties are ignored by the persistent store, and not just during saves...", however this doesn't appear to be the case-- changed transient properties still cause an object to appear in the updated list.


I think you're still missing the point: There is a difference between the change management layer and the persistence layer. The persistence layer (the actual store) does ignore transient properties -- they are not saved to the store and (as the above document notes) cannot be used in fetch predicates -- whereas the change management layer does track changes to transient properties -- a change to a transient property properly does result in an object appearing in the update list. To see an example of why this is so, look at <http:// developer.apple.com/documentation/Cocoa/Conceptual/CoreData/Articles/ cdNSAttributes.html#//apple_ref/doc/uid/TP40001919>.


In fact, simply calling [myManagedObject willChangeValueForKey:@"foobar"] and then [myManagedObject didChangeValueForKey: @"foobar"] on a key that neither appears in the model nor anywhere else in my application ("foobar" in this example) STILL causes the object to appear in [myManagedObjectContext updatedObjects], and hence causes [myManagedObjectContext save:] to re-write the data store.

Invoking the change notification methods flags an object as having changed.
You can probably work about it by disabling undo registration:



- (void)setCurrentDate:(NSDate *)aDate { if (date != aDate) {

        NSManagedObjectContext *moc = [self managedObjectContext];
        [moc processPendingChanges];
        [[moc undoManager] disableUndoRegistration];

        [self willChangeValueForKey:@"currentDate"];

        [currentDate release];
        currentDate = [aDate retain];
        [self didChangeValueForKey:@"currentDate"];
        [[moc undoManager] enableUndoRegistration];
    }
}


Finally, I notice that this seems to have something to do with the Undo machinery, because I am able to perform an "undo" immediately after the minute-timer fires, and if I perform that Undo, then the database is no longer dirty. I tried surrounding my willChange/didChange calls
Umm, what willChange/didChange calls...
[myManagedObject willChangeValueForKey:] and [myManagedObject didChangeValueForKey:]

In general there should be no reason to invoke these methods on any object other than self.


[...]
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id) object change:(NSDictionary*)change context:(void*)context
{
if([keyPath isEqualToString:@"currentDate"] && object == [CAppController appController]) {
// The following triggers observers of the "overdue" attribute
// to update their display of this task. It also
// registers a spurious Undo event, and it also spuriously
// adds this task to the set of changed objects in the
// managed object context. I want it only to trigger the
// update notifications for dependent keys.
[self willChangeValueForKey:@"currentDate"];
[self didChangeValueForKey:@"currentDate"];
}
}


You should not do this. The change notification method invocations should surround the actual change. See the implementation of setCurrentDate: above.


You'll probably also need to invoke processPendingChanges, but it's difficult to say more without knowing exactly what you're doing and why.
Exactly under what circumstances to use processPendingChanges remains a mystery to me. Perhaps the detail I provide above can help you tell me whether this is such a case.

processPendingChanges causes undo events to be registered.


It's not clear that model objects should be observing something in the application. You should probably be sending messages to the model objects from a controller.
While you may be right, as my current pattern causes every fetched task to listen to the "currentDate" attribute of the app controller, I don't see how implementing it differently would result in a fix in my particular situation

It wouldn't -- the comment was about general architecture. Your model objects generally shouldn't have direct access to an app controller.

mmalc

_______________________________________________
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


References: 
 >Re: Core Data: Changing Transient Keys Dirties Database? (From: Robert McNally <email@hidden>)

  • Prev by Date: Re: (Inverse) relationship lost after being set properly
  • Next by Date: Re: Correct way to implement validateValue:?
  • Previous by thread: Re: Core Data: Changing Transient Keys Dirties Database?
  • Next by thread: Re: getting drive/media type (CD/DVD only)
  • Index(es):
    • Date
    • Thread