Search code examples
objective-ccocoa-touchmethodsnsmutablearraysubclass

Should I subclass the NSMutableArray class


I have an NSMutableArray object that I want to add custom methods to. I tried subclassing NSMutableArray but then I get an error saying "method only defined for abstract class" when trying to get the number of objects with the count method. Why is the count method not inherited?

I read somewhere else that I will have to import some NSMutableArray methods into my custom class if I want to use them. I just want to add a custom method to the NSMutableArray class. So should I subclass NSMutableArray, or should I do something else?


Solution

  • NSMutableArray is not a concrete class, it is just the abstract superclass of a class cluster. The documentation for NSMutableArray does have information about how to subclass, but also strongly advises you not to! Only subclass if you have a special need for actual storage.

    A class cluster means that the actual class will be chosen at run-time. An array created empty, may not use the same class as an array created with 1000 items. The run-time can do smart choices of what implementation to use for you. In practice NSMutableArray will be a bridged CFArray. Nothing you need to worry about, but you might see it if you inspect the type of your arrays in the debugger, you will never see NSArray, but quite often NSCFArray.

    As mentioned before, subclassing is not the same as extending a class. Objective-C has the concept of categories. A category is similar to what other programming languages call mix-ins.

    If you for example want a convenience method on NSMutableArray to sort all members on a property, then define the category interface in a .h file as such:

    @interface NSMutableArray (CWFirstnameSort)
    -(void)sortObjectsByProperty:(NSString*)propertyName;
    @end
    

    And the implementation would be:

    @implementation NSMutableArray (CWFirstnameSort)
    -(void)sortObjectsByProperty:(NSString*)propertyName;
    {
        NSSortDescriptor* sortDesc = [NSSortDescriptor sortDescriptorWithKey:propertName ascending:YES];
        [self sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
    }
    @end
    

    Then use it simply as:

    [people sortObjectsByProperty:@"firstName"];