Ordered Sets and NSManagedObjectID
Ordered Sets and NSManagedObjectID
- Subject: Ordered Sets and NSManagedObjectID
- From: Robert McNally <email@hidden>
- Date: Sat, 14 May 2005 21:02:25 -0700
I am writing a Core Data-based application in which I am working towards a solution of the ordered-set problem-- i.e., emulating an (ordered) NSMutableArray container with a (unordered) to-many relationship. In my case, I don't wish to store each element's index as an attribute on the element itself-- I want to leave the elements untouched. Instead, I want the NSMutableArray-like subclass of NSManagedObject to remember the order of the elements and reconstruct their order upon demand after the container is fetched. The main benefit to doing things this way is so that element objects can be shared among multiple container objects.
At first glance doing this appeared to be fairly straightforward-- my container class would have an instance variable which is an actual NSMutableArray that contains references to the contained objects. When my container class updates the unordered (primitive) set of references, it also updates the NSMutableArray, preserving the index information. When my container object receives -willSave, it would take the references in the NSMutableArray and convert them to an ordered representation based on each contained object's persistent object ID ([myContainedObject objectID]) that can be stuffed into one of the primitive CoreData types and set as a property on the container object. When the container receives -awakeFromFetch it would retrieve the ordered representation, convert the archived object IDs back into object references ([managedObjectContext objectWithID:objectID]), and reconstruct the original NSMutableArray.
Here's where my problems begin. The most obvious way of creating the ordered representation at -willSave time is to create an NSString that contains the URI representation of each of the object IDs, separated by spaces. I suppose I could also use NSCoding and archive the NSMutableArray, but I'd like to keep the resultant XML reasonably readable. The first issue is: the documentation says that NSManagedObjectIDs "can be archived and recreated later to refer back to a given object." But it does not give any hints as to the "right" way to perform the archiving.
The situation is complicated by the fact that if I create my container object and then add several element objects to it, all the object IDs are "temporary" and the resultant URI representations reflect this-- it doesn't appear that the temporary representations will survive the round-trip to NSString, persistent store, and back-- I need the permanent ones assigned when NSManagedObjectContext receives -save:.
Here are the URIs for the same object before and after the save (I'm also prepending the value of -isTemporaryID:
BEFORE SAVE
isTemporaryID: 1
0x34e4c0 <x-coredata:///MyManagedObject/tD86BBC11-A378-4DB1-A5B2-38911808A61D>
AFTER SAVE
isTemporary: 0
0x34b730 <x-coredata://8D93298F-07B8-421E-AAB0-87454A41F2B0/MyManagedObject/p102>
Both URIs represent the same object, but the first one is temporary (as indicated by the "t" before the UUID. So what I need is the second representation. But I see no good way to get it without first saving, then retrieving the permanent URI, serializing it, then saving again.
For a minute I thought I had a solution when I realized that the permanent URI is probably assigned in the process of saving when the new object is assigned to a persistent store by the NSPersistentStoreCoordinator. I tried testing this by the following hack:
NSManagedObjectModel* mom = [self managedObjectModel];
NSManagedObjectContext* moc = [self managedObjectContext];
MyManagedObject* obj = [[[MyManagedObject alloc] initWithEntity:[entities objectForKey:@"MyManagedObject"] insertIntoManagedObjectContext:moc] autorelease];
[moc assignObject:obj toPersistentStore:[[[moc persistentStoreCoordinator] persistentStores] objectAtIndex:0]]; // I'm only using one persistent store
NSLog(@"isTemporary: %d\n%@", [[obj objectID] isTemporaryID], [obj objectID]);
I had hoped the result would be a permanent URI representation. Instead, I received a new and unfamiliar temporary representation!
AFTER ASSIGN TO PERSISTENT STORE BUT BEFORE SAVE
isTemporary: 1
0x34e4c0 <x-coredata://8D93298F-07B8-421E-AAB0-87454A41F2B0/MyManagedObject/tD86BBC11-A378-4DB1-A5B2-38911808A61D>
This seems to be a halfway representation containing two UUIDs-- the first is the one that appears in the URI after the save, and the second is the temporary UUID, including the prepended "t". It also appears to be missing the "/p102" suffix that appears in the post-save version, so I can't even really construct a permanent URI through string manipulation (and this seems like a hopelessly bad thing to do anyway.)
So I have no idea how to get a "real" URI that I can trust to make the round trip. Any suggestions?
Robert
--
______________________________________________________________________
Robert McNally, Arciem Engineering <http://www.arciem.com>
626/963-7760
_______________________________________________
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