Re: Core Data: Insert, Fetch, Re-Fetch. Same Object?
Re: Core Data: Insert, Fetch, Re-Fetch. Same Object?
- Subject: Re: Core Data: Insert, Fetch, Re-Fetch. Same Object?
- From: Alexander Spohr <email@hidden>
- Date: Thu, 11 Feb 2010 09:19:01 +0100
Am 11.02.2010 um 04:07 schrieb Jerry Krinock:
>
> On 2010 Feb 10, at 18:05, Jens Alfke wrote:
>
>>> I've always wondered if I insert a managed object, then later fetch it repeatedly from the same managed object context, do I get the same object every time?
>>
>> Yes, basically. There is only going to be one in-memory object at a time that represents the same managed object.
>
> It certainly seems to be sensible, but I just wish someone could find such documentation. I can't.
Every NSManagedObjectContext holds its own but unique copy of your object.
> In the last few minutes here, I improved my demo to test an sqlite store as well as an in-memory store, and also I setStalenessInterval to 0 and threw in some -refreshObject:mergeChanges:NO and more saves. The only difference I found was that, while the in-memory store fetches the same object that you inserted, the sqlite store does not, although subsequent fetches return the same object.
This is because the object in the sql-store needs a primary key. As long as it was not saved it has a temporary key only. When saved it gets a persistent key.
After that it is identifiable by this and therefore you get alwas the same object back.
I would have thought that your inserted object gets the persistent key set and will therefore be the same object as the fetched ones. But I did not check your code for a misconfiguration.
> Can anyone guarantee this?
> I would imagine that, even though it's not documented, Apple must realize that if they were ever to change this behavior, it would probably break alot of apps which have been relying on it without the designers realizing this. Would Apple ever ever do anything like that?
No, you will always get the same object. Because this was why CoreData and EOF where made for. Exactly this.
atze
> Jerry
>
>
> REVISED CONSOLE OUTPUT:
>
> Using sqlite store at /Users/jk/Desktop/FooTest.sqlite
> Inserted: Foo 0x30022c0 name=Murphy ivar=BeenInserted
> First Fetched: Foo 0x3006120 name=Murphy ivar=BeenFetched
> Second Fetched: Foo 0x3006120 name=Murphy ivar=BeenFetched
> Delay Fetched: Foo 0x3006120 name=Murphy ivar=BeenFetched saved=1
> Delay Fetched: Foo 0x3006120 name=Murphy ivar=BeenFetched saved=1
>
> Using in-memory store
> Inserted: Foo 0x300c1a0 name=Murphy ivar=BeenFetched
> First Fetched: Foo 0x300c1a0 name=Murphy ivar=BeenFetched
> Second Fetched: Foo 0x300c1a0 name=Murphy ivar=BeenFetched
> Delay Fetched: Foo 0x300c1a0 name=Murphy ivar=BeenFetched saved=1
> Delay Fetched: Foo 0x300c1a0 name=Murphy ivar=BeenFetched saved=1
>
>
> REVISED DEMO PROJECT:
>
> #import <Foundation/Foundation.h>
> #import <CoreData/CoreData.h>
>
> @interface Foo : NSManagedObject
> {
> NSString* m_ivar ;
> }
>
> @property (copy) NSString* ivar ;
>
> @end
>
> @implementation Foo
>
> @synthesize ivar = m_ivar ;
>
> - (void)dealloc {
> [m_ivar release] ;
>
> [super dealloc] ;
> }
>
> - (NSString*)description {
> return [NSString stringWithFormat:
> @"Foo %p name=%@ ivar=%@",
> self,
> [self valueForKey:@"name"],
> [self ivar]] ;
> }
>
> @end
>
>
> // Note: This function returns a retained, not autoreleased, instance.
> NSManagedObjectModel *getStaticManagedObjectModel() {
> static NSManagedObjectModel *mom = nil;
>
> if (mom != nil) {
> return mom;
> }
>
> mom = [[NSManagedObjectModel alloc] init];
>
> NSEntityDescription *fooEntity = [[NSEntityDescription alloc] init];
> [fooEntity setName:@"Foo"];
> [fooEntity setManagedObjectClassName:@"Foo"];
> [mom setEntities:[NSArray arrayWithObject:fooEntity]];
>
> NSMutableArray* properties = [[NSMutableArray alloc] init] ;
> NSAttributeDescription *attributeDescription;
>
> // Add an attribute. (Copy this section to add more attributes.)
> attributeDescription = [[NSAttributeDescription alloc] init];
> [attributeDescription setName:@"name"];
> [attributeDescription setAttributeType:NSStringAttributeType];
> [attributeDescription setOptional:YES];
> [properties addObject:attributeDescription] ;
> [attributeDescription release] ;
>
> [fooEntity setProperties:properties];
> [properties release] ;
>
> [fooEntity release] ;
>
> return mom;
> }
>
> // Note: This function returns a retained, not autoreleased, instance.
> NSManagedObjectContext *getStaticManagedObjectContext() {
>
> static NSManagedObjectContext *moc = nil;
>
> if (moc != nil) {
> return moc;
> }
>
> moc = [[NSManagedObjectContext alloc] init];
>
> NSPersistentStoreCoordinator *coordinator =
> [[NSPersistentStoreCoordinator alloc]
> initWithManagedObjectModel:getStaticManagedObjectModel()];
> [moc setPersistentStoreCoordinator: coordinator];
> [coordinator release] ;
>
> NSError *error;
> NSPersistentStore *newStore ;
> #if 0
> NSLog(@"Using in-memory store") ;
> newStore = [coordinator addPersistentStoreWithType:NSInMemoryStoreType
> configuration:nil
> URL:nil
> options:nil
> error:&error];
> #else
> #warning USING_SQLITE_STORE
> NSString* path = NSHomeDirectory() ;
> path = [path stringByAppendingPathComponent:@"Desktop"] ;
> path = [path stringByAppendingPathComponent:@"FooTest.sqlite"] ;
> NSLog(@"Using sqlite store at %@", path) ;
> NSURL* url = [NSURL fileURLWithPath:path] ;
> newStore = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
> configuration:nil
> URL:url
> options:nil
> error:&error];
> #endif
>
> if (newStore == nil) {
> NSLog(@"Store Configuration Failure\n%@",
> ([error localizedDescription] != nil) ?
> [error localizedDescription] : @"Unknown Error");
> }
> return moc;
> }
>
>
> @interface DelayedFetcher : NSObject {
> }
>
> @end
>
> @implementation DelayedFetcher
>
> + (void)fetchFoo:(NSTimer*)timer {
> NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
> NSManagedObjectContext *moc = getStaticManagedObjectContext() ;
> [fetchRequest setEntity:[NSEntityDescription entityForName:@"Foo"
> inManagedObjectContext:moc]];
> NSArray* fetches = [moc executeFetchRequest:fetchRequest
> error:NULL] ;
> [fetchRequest release] ;
> Foo* delayFetchedFoo = [fetches objectAtIndex:0] ;
> [moc refreshObject:delayFetchedFoo
> mergeChanges:NO] ;
> #if 1
> BOOL didSave = [moc save:NULL] ;
> #else
> BOOL didSave = NO ;
> #endif
> NSLog(@" Delay Fetched: %@ saved=%d", delayFetchedFoo, didSave) ;
> }
>
> @end
>
>
> int main (int argc, const char * argv[])
> {
> NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
>
> // Create Core Data stack
> NSManagedObjectModel *mom = getStaticManagedObjectModel();
> NSManagedObjectContext *moc = getStaticManagedObjectContext();
>
> [moc setStalenessInterval:0.0] ;
>
> // Insert a Foo and name it "Murphy"
> Foo* insertedFoo = [NSEntityDescription insertNewObjectForEntityForName:@"Foo"
> inManagedObjectContext:moc] ;
> [insertedFoo setValue:@"Murphy"
> forKey:@"name"] ;
>
> // Set an ivar
> [insertedFoo setIvar:@"BeenInserted"] ;
>
> [moc processPendingChanges] ;
> [moc save:NULL] ;
>
> NSFetchRequest* fetchRequest ;
> NSArray* fetches ;
>
> [moc refreshObject:insertedFoo
> mergeChanges:NO] ;
>
> // Fetch the Foo
> fetchRequest = [[NSFetchRequest alloc] init];
> [fetchRequest setEntity:[NSEntityDescription entityForName:@"Foo"
> inManagedObjectContext:moc]];
> fetches = [moc executeFetchRequest:fetchRequest
> error:NULL] ;
> [fetchRequest release] ;
> Foo* firstFetchedFoo = [fetches objectAtIndex:0] ;
>
> [firstFetchedFoo setIvar:@"BeenFetched"] ;
>
> // Fetch the Foo again
> fetchRequest = [[NSFetchRequest alloc] init];
> [fetchRequest setEntity:[NSEntityDescription entityForName:@"Foo"
> inManagedObjectContext:moc]];
> fetches = [moc executeFetchRequest:fetchRequest
> error:NULL] ;
> [fetchRequest release] ;
> Foo* secondFetchedFoo = [fetches objectAtIndex:0] ;
>
> // See what we got
> NSLog(@" Inserted: %@", insertedFoo) ;
> NSLog(@" First Fetched: %@", firstFetchedFoo) ;
> NSLog(@"Second Fetched: %@", secondFetchedFoo) ;
>
> // Create a run loop
> NSRunLoop* runLoop = [NSRunLoop currentRunLoop] ;
>
> [NSTimer scheduledTimerWithTimeInterval:1.0
> target:[DelayedFetcher class]
> selector:@selector(fetchFoo:)
> userInfo:nil
> repeats:YES] ;
> [runLoop run] ;
>
> [moc release] ;
> [mom release] ;
> [pool release] ;
>
> return 0;
> }_______________________________________________
>
> 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
_______________________________________________
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