1

I've run into some problems using NSManagedObjectID and it changing depending on it's saved state.

As such I've decided to use my own UniqeIDs as recommended in the docs and by others. I've seen many examples here on Stack Overflow and on other places where it's a simple matter of storing a NSUUID string value in a core data field.

However, this isn't quite enough for what I want. One of the useful things about NSManagedObjectID is that it is always the same object and can be compared by pointer, so you can post notifications around using the NSManagedObjectID as their object, anything that requires information about the entity can register for notification based on the NSManagedObjectID without writing additional code to check if the notification is indeed the one we're looking for.

However, would that be still be true if an NSString is passed around instead of the NSManagedObjectID? We're always supposed to use isEqualTo for NSString comparison, even if it might be the same object. I feel like using an NSString as an object for a notification is a bit of a no no.

In my case, it's pretty much guaranteed be the same object, unless objective c messes around with NSString behind the scenes. the uniqueID is generated once on insertion of an object, and would be passed around unaltered as required, and I simply want to replace all calls where I use NSManagedObjectID with something I can drop in with minimal changes.

A CFUUID would seem ideal, as they can be guaranteed to share pointer values, however CFUuidRef is not an objective-c object, so can't be used for notifications among other things. An NSUUID seems next to best apart from the caveat in the documentation that says they aren't guaranteed to be the same object. But if my NSUUID is created, stored and retrieved on a single object, could we guarantee the passed around NSUUID to be the same object throughout the application? If so, couldn't we say the same thing about an NSString? Even if we could, I'd be happier just going with NSUUID.

I can't pass around the Entity directly, as I'm using the notification to post information between separate threads. Even though I only ever modify the entities on the main thread, and entities can be accessed for readonly across threads, I've had many problems in the past, that all went away once I implemented a system based on using just the NSManagedObjectID.

George Brown
  • 1,134
  • 10
  • 25

1 Answers1

0

Maybe I got you wrong, but why not passing around instances of NSUUID (if you do not want to use instances of NSString) and comparing them on equality?

@interface NSUUID(Equality)
- (BOOL)isEqualToUUID:(NSUUID*)other;
@end

@implementation NSUUID(Equality)
- (BOOL)isEqualToUUID:(NSUUID*)other
{
   return [self.UUIDString isEqualToString:other.UUIDString];
}

// Only for completness
- (BOOL)isEqual:(id)other
{
  if( [other isKindOfClass:[NSUUID class]] )
  {
    return [self isEqualToUUID:other];
  }
  return NO;
}
@end

BTW: The same reasons that make you feel badly using instances of NSString as notification object does not apply to instances of NSUUID?

BTW 2: Handling CF-objects in ARC code is not that difficult.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • Specifically because i want to filter notifications using the ID as the object of the notification, so i can post and register notifications with minimal checking and extra code. This is possible with nsmanagedobjectid. I realise the distinction between nsstring and nsuuid would be negligible in this case, more a convention, but i have the feeling nsstring has additional compiler checks. – George Brown Jun 30 '15 at 13:09
  • So the above code should work. Or did I get you wrong? – Amin Negm-Awad Jun 30 '15 at 13:22
  • Actually not sure, the NSNotification documentation specifically states pointer equality is checked for local notifications, is overriding isEqual: all that's required? If so i guess so, but i'd probably create a new subclass of nsuuid rather than override in a category. – George Brown Jun 30 '15 at 13:54
  • Ah, yes, you are correct. Yes, subclassing or having a simple method that returns an unified UUID from a given UUID. When subclassing you have to take into account that `NSUUID` conforms to `NSCopying`. (And `NSSecureCoding`, but likely you simply do not care about that.) – Amin Negm-Awad Jun 30 '15 at 18:41
  • I'm playing around with the changes in my app at the moment, Just converted most of my stuff that uses NSManagedObjectIDs to generated unique IDs, still a few things to iron out before playing around with the finer intricacies of this problem... Thanks for the hints so far. – George Brown Jun 30 '15 at 21:47