开发者

Choosing unique label for NSManagedObject in CoreData

开发者 https://www.devze.com 2023-03-22 04:29 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消