Skip to content


Subversion checkout URL

You can clone with
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 3 files changed
  • 7 commit comments
  • 1 contributor
2  Source/Model/MJGSortedMutableArray.h
@@ -21,6 +21,8 @@
- (id)initWithSelector:(SEL)selector;
- (NSUInteger)addObject:(id)obj;
+- (NSArray*)addObjects:(NSArray*)objects;
+- (void)addObjects:(NSArray*)objects addedIndices:(NSUInteger*)indices;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)removeAllObjects;
- (id)objectAtIndex:(NSUInteger)index;
30 Source/Model/MJGSortedMutableArray.m
@@ -106,6 +106,36 @@ - (NSUInteger)addObject:(id)obj {
return addedIndex;
+- (NSArray*)addObjects:(NSArray*)objects {
+ NSUInteger *indices = malloc(sizeof(NSUInteger) * objects.count);
+ [self addObjects:objects addedIndices:indices];
+ NSMutableArray *returnArray = [NSMutableArray new];
+ for (NSUInteger i = 0; i < objects.count; i++) {
+ [returnArray addObject:[NSNumber numberWithUnsignedInteger:indices[i]]];
+ }
+ if (indices) {
+ free(indices);
+ }
+ return [returnArray copy];
+- (void)addObjects:(NSArray*)objects addedIndices:(NSUInteger*)indices {
+ [objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ NSUInteger index = [self addObject:obj];
+ if (indices) {
+ indices[idx] = index;
+ for (NSUInteger i = 0; i < idx; i++) {
+ if (indices[i] >= index) {
+ indices[i] = indices[i] + 1;
+ }
+ }
+ }
+ }];
- (void)removeObjectAtIndex:(NSUInteger)index {
[_backingArray removeObjectAtIndex:index];
21 Tests/MJGSortedMutableArrayTests/Source/MJGSortedMutableArrayTests.m
@@ -89,4 +89,25 @@ - (void)testEnumerating {
+- (void)testMultipleInsertion {
+ NSArray *descriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"intValue" ascending:YES]];
+ self.array = [[MJGSortedMutableArray alloc] initWithDescriptors:descriptors];
+ NSArray *objectsToAdd = [[NSArray alloc] initWithObjects:
+ [NSNumber numberWithInt:0],
+ [NSNumber numberWithInt:2],
+ [NSNumber numberWithInt:4],
+ [NSNumber numberWithInt:1],
+ [NSNumber numberWithInt:3],
+ nil];
+ NSArray *addedIndices = [_array addObjects:objectsToAdd];
+ STAssertEquals(addedIndices.count, (NSUInteger)5, @"Incorrect number of indices returned");
+ STAssertEquals([[addedIndices objectAtIndex:0] unsignedIntegerValue], (NSUInteger)0, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:1] unsignedIntegerValue], (NSUInteger)2, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:2] unsignedIntegerValue], (NSUInteger)4, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:3] unsignedIntegerValue], (NSUInteger)1, @"Incorrect index returned");
+ STAssertEquals([[addedIndices objectAtIndex:4] unsignedIntegerValue], (NSUInteger)3, @"Incorrect index returned");

Showing you all comments on commits in this comparison.


Rather than messing around with NSNumber or C arrays, I suggest implementing a single -addObjectsFromArray: method that returns an NSIndexSet


Yep that would be nicer. I'd still like to expose the C-array style interface (although it does need documenting as you have to free() it) but yes it should be an NSIndexSet. Pull requests accepted :-).


Why are you interested in keeping the C-array style interface? What benefit does it have?


It's quicker if you know what you're doing with it. Although, granted, the "overhead" of creating the NSIndexSet really won't be all that much. Perhaps premature optimisation I must admit.


I suspect in reality it would not be the bottleneck. If you particularly need to add a large number of objects at once, I'd expect to find that the bottleneck is either:

  • Creating the index set or C array. Both have a similar cost as both are allocating memory; iterating the array yourself and calling -addObject: is faster
  • Inserting the objects into the underlying storage. In which case, using -insertObjects:atIndexes: internally is the answer, as it gives NSMutableArray a better idea of its allocation needs, and therefore you've already spent time to create an index set

I agree with you. In my particular use case I wanted the C-array method exposed but I agree that for the general case it might not be best exposed. I'll take a look as soon as I get time to making it use NSIndexSet, not expose the C-array method and inheriting from NSArray. In the meantime, pull requests are gladly accepted.


Great! I'll dive in myself if I get a chance

Something went wrong with that request. Please try again.