1

According to NSArray class reference there are 4 type of methods to sort array:

1- sortedArrayUsingComparator:

2- sortedArrayUsingSelector:

3- sortedArrayUsingFunction:context:

4- sortedArrayUsingDescriptors:

For first three methods it mentioned : The new array contains references to the receiving array’s elements, not copies of them. But for the forth method (descriptor) it mentioned: A copy of the receiving array sorted as specified by sortDescriptors.

But following example shows like the other 3 methods, descriptor also retain original array and do not return a new copy of it:

NSString *last = @"lastName";
NSString *first = @"firstName";

NSMutableArray *array = [NSMutableArray array];
NSDictionary *dict;

NSMutableString *FN1= [NSMutableString stringWithFormat:@"Joe"];
NSMutableString *LN1= [NSMutableString stringWithFormat:@"Smith"];

NSMutableString *FN2= [NSMutableString stringWithFormat:@"Robert"];
NSMutableString *LN2= [NSMutableString stringWithFormat:@"Jones"];

dict = [NSDictionary dictionaryWithObjectsAndKeys: FN1, first, LN1, last, nil];
[array addObject:dict];

dict = [NSDictionary dictionaryWithObjectsAndKeys: FN2, first, LN2, last, nil];
[array addObject:dict];

// array[0].first = "Joe"    ,  array[0].last = "Smith"  
// array[1].first = "Robert" ,  array[1].last = "Jones" 

NSSortDescriptor *lastDescriptor =[[NSSortDescriptor alloc] initWithKey:last
                                                          ascending:YES
                                 selector:@selector(localizedCaseInsensitiveCompare:)];

NSSortDescriptor *firstDescriptor =[[NSSortDescriptor alloc] initWithKey:first
                                                           ascending:YES
                                 selector:@selector(localizedCaseInsensitiveCompare:)];

NSArray *descriptors = [NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil];

NSArray *sortedArray = [array sortedArrayUsingDescriptors:descriptors];

//    array[1] == sortedArray[0] == ("Robert" ,  "Jones")     
//    comparing array entries whether they are same or not:

NSLog(@"  %p  , %p " , [array objectAtIndex:1]  , [sortedArray objectAtIndex:0]  );
//  0x10010c520  ,  0x10010c520

it shows objects in both arrays are same,

Hadi
  • 151
  • 7

1 Answers1

2

"A copy of the receiving array sorted as specified by sortDescriptors" means that the array object is copied not the elements in the array. The reason the documentation uses the word "copy" is to make it clear that the returned array is not the same array instance as the receiver.

Elements in an array are never copied in Cocoa with the exception of initWithArray:copyItems:YES which will copy the first level items in the original array to the new array. Even then, this copy is done by calling copyWithZone: on the elements, so caveats apply depending on what elements are in your array.

Note that Cocoa is reference counted, so the concept of "deep copies" is not inherently built in for a reason. This is also (in part) the reason why array objects in cocoa come in two flavors (NSArray and NSMutableArray) and are usually immutable (NSArray) instead of as in other languages where there is not usually a concept of immutable and mutable arrays.

see this SO answer for how to get a "deep copy" of an NSArray.

Community
  • 1
  • 1
Brad Allred
  • 7,323
  • 1
  • 30
  • 49
  • as you say it will do a shallow copy like first 3 mentioned method, but in that reference it obviously mentioned that copy of objects will placed in sorted array, moreover you can copy nested arrays into new one using TRUE DEEP COPY technique which copies all levels – Hadi Dec 03 '13 at 16:11
  • @Hadi you are misinterpreting the documentation. it does not say that the objects will be copied. – Brad Allred Dec 03 '13 at 16:14