Search code examples
objective-cnsarraynsset

Why is [NSSet allObjects] not returning an array of objects in the set


I'm following a [NSManagedObject valueForKeyPath:...] and then checking the result returned by that query to see whether it's a single NSManagedObject, or an NSSet of managed objects. If it's an NSSet, i'm trying to transfer it to an NSArray using [NSSet allObjects]

It is not returning an NSArray of the members of the NSSet as expected.

guids = [result allObjects]

result is in fact an NSSet, but it's giving me back an array with the NSSet inside it.

When I ask the array how many objects are in it, I get '1' as my answer...

[guids count] // returns 1

    NSArray *guids;

    id result = [someNSManagedObject valueForKeyPath:kvcPath];

    if ([result isKindOfClass:[NSSet class]])
    {
        guids = [result allObjects];
    }

enter image description here

Even replacing the guids = [result allObjects] with an enumerator and an NSMutableArray doesn't work...

    if ([result isKindOfClass:[NSSet class]])
    {
        NSEnumerator *setEnumerator = [result objectEnumerator];
        NSString *value;

        while (value = [setEnumerator nextObject]) {
            [guids addObject:value];
        }
    }

Look at the picture below (hilarious), the enumerator supposed to be looking at a single value from the set, but it's instead looking at the entire set as the value.

enter image description here


Solution

  • With credit to rmaddy in the comments above, it turns out this is an NSSet within an NSSet.

    Contrast these two paths for the explanation that follows

    someParentManObj.someRelatedChildManObj

    versus

    someParentManObj.someRelatedChildManObj.someFieldOnChildManObj

    Apparently, if you follow NSManagedObject paths just to a relationship, and no further, such as a field, then you'll get back either ... (1) a single NSManagedObject at the other end of the relationship, or (2) an NSSet of NSManagedObjects at the other end of the relationship.

    However, if you tweak the path such that it ends in a field name on a NSManagedObject, you won't get an NSSet of values, rather you get an NSSet wrapped in an NSSet.