I have an array of segments
each has an array of fighters
associated with it.
The relationship can be described thusly:
One `segment` can have many `fighters`
The objects are managed by core data.
When displayed in a table view each cell has two buttons so a user can pick a fighter from a seperate view controller; and it then when it returns it will update the segment fighter relationship.
Because the relationship of segment.fighters
a non-mutable NSSet
, I need to modify it so that;
If
User presses left button, this infers that the first object in the segment.fighter is being picked
User presses right button, it infers that the last object in the segment.fighter is being picked
When I come to Update the relationship, sometimes; depending on the sequence of buttons pressed by the user; the positions of the objects in the NSSet
are inverted.
ie:
Sometimes a fighter that should be at position 0 is swapped with a fighter at position 1, when this should never happen.
My code is as follows;
NSArray *currentFighters = [[segment valueForKeyPath:@"fighters"] allObjects];
NSLog(@"----- current fighters ---- ");
for (FCFighter *fighter in currentFighters) {
NSLog(@"%@", [fighter description]);
}
NSMutableArray *currentFightersMutable = [currentFighters mutableCopy];
[currentFightersMutable replaceObjectAtIndex:fighterIdx withObject:pickedFighter];
NSArray *updatedFighters = [currentFightersMutable copy];
NSLog(@"----- updated fighters ---- ");
for (FCFighter *fighter in updatedFighters) {
NSLog(@"%@", [fighter description]);
}
[segment setFighters:[NSSet setWithArray:updatedFighters]];
NSLog(@"----- [segment fighters] ---- ");
for (FCFighter *fighter in [[segment valueForKeyPath:@"fighters"] allObjects]) {
NSLog(@"%@", [fighter description]);
}
I am using a NSMutableArray so that I can replace the exact object in the array.
I can prove that it works via logs
Picked fighter - AJ Fonseca
----- current fighters ----
AJ Matthews
A Sol Kwon
----- updated fighters ----
AJ Fonseca
A Sol Kwon
----- [segment fighters] ---- // NOTE it has swapped them, but why?
A Sol Kwon
AJ Fonseca
-[FCSegmentTableViewCell configureCellWithSegment:]
#0 -- A Sol Kwon
#1 -- AJ Fonseca
However when it gets to segment fighters output, the fighters are swapped; but my question is --
Why does the NSSet invert my array?
Many thanks
An NSSet
is an unordered collection of objects. The property allObjects
which you use returns an array, but as the documentation for this method states "The order of the objects in the array is undefined.".
Because of this, whenever you try and get an array out of your set, you could get a different order.
To make sure the orders don't change, you should either a) use an ordered relationship for the fighters - but not a good idea as NSOrderedSet
is a mix between an array and a set. b) apply a sort to the array returned from allObjects
so that the order is consistent. This is my preferred method.