Search code examples
objective-creactive-cocoa

How can I make sure that an NSArray is always sorted, using ReactiveCocoa?


Let's say that I have a ColorListViewModel whose model is an array of Color objects:

@property (nonatomic, copy) NSArray *colors;

and I update the entire model when a command is executed:

RAC(self, colors) = [_fetchColorsCommand.executionSignals flatten];

while also having an addColor: method which does the following:

- (void)addColor:(Color *)color
{
    NSMutableArray *mutableColors = [self.colors mutablecopy];
    [mutableColors addObject:color];
    self.colors = [mutableColors copy];
}

I could sort the array of colors (by name, for example) in multiple places using NSSortDescriptor.

How can I subscribe to changes to self.colors and perform the sorting there? So far my attempts to do this have resulted in an infinite loop.


Solution

  • well it depends on if you do more inserting or more reading...

    if you do a lot of inserting and not a lot of reading, then you could sort lazily... both of these examples require you to define -(NSComparisonResult)compareColor:(id)someOtherColor... you could also use a block or function.

    - (NSArray *)colors
    {
       return [_colors sortedArrayUsingSelector:@selector(compareColor:) ];
    }
    

    or you could sort up front on insert, if you read more frequently

    - (void)addColor:(Color *)color
    {
        NSMutableArray *mutableColors = [self.colors mutablecopy];
        [mutableColors addObject:color];
        self.colors = [mutableColors sortedArrayUsingSelector:@selector(compareColor:)];
    }