Choosing unique label for NSManagedObject in CoreData
I'm searching for a better alternative to deal with this problem.
In a CoreData model I have an NSManagedObject called Project. In its subclass I override the accessor method (setter) for its label attribute. Here I check whether the same label is already used. If it is, I add开发者_运维技巧 an underscore and a number to the label, e.g. "MyProject" is renamed to "MyProject_1". Of course I also have to check whether I find the label "MyProject" or "MyProject_"+number. I do that with a Regular Expression.
NSString *regexString = [NSString stringWithFormat:@"%@_[0-9]+", value];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(label = %@) OR (label MATCHES %@)", value, regexString];
[request setPredicate:predicate];
Then I check how many results are fetched, lets say 5, so I know that the next one hast to be called "MyProject_6".
It works fine but you probably have already noticed that there is a little problem with this code: What happens if I have the following labels:
MyProject_1, MyProject_2, MyProject_3
and the user decides to call a project MyProject_55. Then my search would retrieve 4 elements and the next project would be labeled MyProject_5 instead of MyProject_4. And what it's worse, at some point, I would end up having two MyProject_55. I know it's unlikely to happen, but it can :).
Any ideas for something better?
Here's the accessor method
#pragma mark - Setter for label
- (void)setLabel:(NSString *)aLabel
{
if ([[self primitiveValueForKey:@"label"] isEqualToString:aLabel])
{
return;
}
NSMutableArray *objects = [self fetchObjectsWithValueEqualTo:aLabel];
NSUInteger objectsCount = [objects count];
aLabel = objectsCount > 0 ? [NSString stringWithFormat:@"%@_%d",aLabel, objectsCount] : aLabel;
[self willChangeValueForKey:@"label"];
[self setPrimitiveValue:aLabel forKey:@"label"];
[self didChangeValueForKey:@"label"];
}
Its a little expensive but the simplest way out of this dilemma is once you have a new label decision "MyLabel_4" recheck if that label exists in the store.
Rinse and repeat until you really have a unique label. Core Data is very efficient so this isnt going to matter in a userland case.
精彩评论