Skip navigation.
 
mlrefreshObject:mergeChanges: vs. stale transient properties
FROM : Jakob Olesen
DATE : Tue Aug 01 09:18:52 2006

Sorry to steal the subject of an old thread: http://lists.apple.com/
archives/cocoa-dev/2005/Aug/msg00572.html

The problem is when implementing non-standard attributes as described 
in the Core Data Programming Guide, refreshObject:mergeChanges:YES no 
longer works as expected. The documentation says that transient 
attributes are unaffected by refreshObject:mergeChanges:YES, so when 
using "The Pre-calculated Get" pattern you get the old value since it 
is cached in a transient attribute.

Jim Correia solved his problem by setting a flag:

- (void)didTurnIntoFault
{
    transientValueStale = YES;
    [super didTurnIntoFault];
}

and then checking it in the attribute accessor method.

But this doesn't work if the value has been changed! When using "The 
Delayed-Update Set Accessor" refreshObject:mergeChanges:YES now 
behaves like refreshObject:mergeChanges:NO, forgetting the changed 
value. I haven't tried it, but I think "The Immediate-Update Set 
Accessor" is OK in this situation. It has performance issues, though, 
especially if you're archiving something larger than an NSColor.

Has anybody solved this problem? A transientValueChanged flag would 
be hard to maintain across undo/redo.


On a related issue, suppose the following code, where "color" is a 
transient attribute:

- (void)awakeFromFetch
{
    [super awakeFromFetch];
    [self setPrimitiveValue:[NSColor redColor] forKey:@"color"];
}

Now, this works as advertised:

[obj setValue:[NSColor blueColor] forKey:@"color"];
[moc refreshObject:obj mergeChanges:YES];
c = [obj valueForKey:@"color"] ;
// c is blue here


But this:

[obj setValue:nil forKey:@"color"];
[moc refreshObject:obj mergeChanges:YES];
c = [obj valueForKey:@"color"] ;
// c is red, not nil!

That is, refreshObject:mergeChanges:YES does in fact affect transient 
attributes. If a transient attribute is nil before the call, it will 
retain the value given to it by awakeFromFetch. That is not how 
persistent attributes work.

Is that a bug or a feature?

It think it might be useful with two new callbacks, so that for 
refreshObject:mergeChanges:YES, the managed object sees:

- willRefreshAndMergeChanges
- didTurnIntoFault
- awakeFromFetch
- didRefreshAndMergeChanges

Related mailsAuthorDate
mlrefreshObject:mergeChanges: vs. stale transient properties Jakob Olesen Aug 1, 09:18
mlRe: refreshObject:mergeChanges: vs. stale transient properties Jakob Olesen Aug 5, 03:01