0

Class "Person" is inherited by "Employee" which is inherited by "EmployeeList"

In my main model I initialize a new Employee object, setting the firstName and lastName, and then addEmployee to an EmployeeList.

Inside the addEmployee method I want to sort the NSArray of Employee objects by lastName

Here is what I've tried but it's not sorting the list.

#import "EmployeeList.h"

@interface EmployeeList()
@property (strong, nonatomic) NSMutableArray *employees;  // of Employee
@end


@implementation EmployeeList

- (NSMutableArray *)employees
{
    if (!_employees) _employees = [[NSMutableArray alloc] init];
    return _employees;
}

- (void)addEmployee:(Employee *)employee
{
    [self.employees addObject:employee];

    NSSortDescriptor *sortDescriptor =
    [NSSortDescriptor sortDescriptorWithKey:@"lastName"
                                  ascending:YES
                                   selector:@selector(caseInsensitiveCompare:)];
    [self.employees sortedArrayUsingDescriptors:@[sortDescriptor]];

    _numberEmployees++;
}

Main model:

EmployeeList *mgrList = [[EmployeeList alloc] init];

Employee *employee = [[Employee alloc] init];
employee.firstName = object[@"firstName"];
employee.lastName  = object[@"lastName"];
employee.phoneNumber = object[@"phoneNumber"];

[mgrList addEmployee:employee];
4
  • So does Employee have a method called caseInsensitiveCompare:? I doubt (because that's an NSString method). Read the documentation of NSSortDescriptor and think about your code. Commented May 4, 2014 at 22:55
  • 1
    Why the down vote? Please let me know so I can learn. Commented May 4, 2014 at 22:57
  • Provide details about the crash. Commented May 4, 2014 at 22:58
  • Actually, I've realized the crash was unrelated and solved the crash. Commented May 4, 2014 at 23:00

2 Answers 2

2

Change this:

[self.employees sortedArrayUsingDescriptors:@[sortDescriptor]];

to:

[self.employees sortUsingDescriptors:@[sortDescriptor]];
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, that makes more sense now and solved my problem. I've spent a lot of time on this simple problem as I'm pretty new to Obj-C.
sortedArrayUsingDescriptors: doesn't sort the original array, it returns a new sorted array.
1

Ok your code need a refactor:

#import "EmployeeList.h"

@interface EmployeeList()
@property (strong, nonatomic) NSMutableArray *employees;  // of Employee
@end


@implementation EmployeeList

//This is a more elegant solution to init
- (NSMutableArray *)employees
{
    dispatch_token_t token;
    dispatch_once(&token, ^{
        _employees = [NSMutableArray new];
    });
    return _employees;
}

- (void)addEmployee:(Employee *)employee
{
    [self.employees addObject:employee];

    NSSortDescriptor *sortDescriptor =
    [NSSortDescriptor sortDescriptorWithKey:@"lastName"
                                  ascending:YES
                                   selector:@selector(caseInsensitiveCompare:)];

    //This return an array so if you don't take it you don't have any change.
    NSArray *newArray = [[self.employees copy] sortedArrayUsingDescriptors:@[sortDescriptor]];

    //Then you can remove and add again all the object to the NSMutableArray
    [self.employees removeAllObjects];
    [self.employees addObjectsFromArray:newArray];

    //This is not needed because you can access to this information by
    //[self.employees count]
    //_numberEmployees++;
}

Be careful because you self.employees is mutable.

5 Comments

i know that is inefficient, just took the code of the user. He says that the crash was unrelated and so i think that his problem was just that didn't save the array. EDIT: You deleted your comment and down vote, and you focus the problem by my response providing a little bit different answer..fox..np!
My original comment was based on the original question which was about a crash. After the question was updated to simply point out the actual problem, I posted my answer. I originally down voted because your answer had nothing to do with a crash. But please be aware that your solution is really not a good way to sort an existing mutable array. There is no reason to create an immutable copy of the array, create a new, sorted array, clear out the original mutable array, and then populate the empty mutable array with the sorted array. Just use one method to sort the mutable array in place.
Sure, you are right but not on every thing. Your code is better because sort the array locally, but is not safe. If i add something to the array while is ordering, the app crash. You need to use some synchronized scope or use immutable copy. In any case, i would have write my code totally in another way.
There was nothing in the question about needing to be thread-safe. That's a whole other level of complexity beyond this question.
There was nothing about performance as well..nay, i used the same code of the user. I know of the performance, and you should about the thread safe

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.