I am trying to subclass NSArray
, but it crashes the app when trying to access the count method. I know that NSArray
is a class cluster.
- But what does this mean?
- Is there a work around to be able to subclass an NSArray?
I know that I can simply subclass NSObject
and have my array as an instance variable but I would rather subclass NSArray
.
EDIT:
Reason:
I am creating a card game, I have a class Deck
which should subclass NSMutableArray
to have a couple of extra methods (-shuffle
, -removeObjects:
, -renew
, etc), and I think it will look cleaner to subclass NSArray
rather than having a var.
The problem with adding a category on a class like this is that all instances of the class will inherit the additional methods. That's both unnecessary (since not every array needs to be able to be shuffled, etc.) and dangerous (because you can't benefit from typechecking to be sure the NSArray you're currently referring to is really one that was expected to be shuffled).
An alternative would be to create your own Deck class that has an NSMutableArray as an instance variable. There you can define actions on your deck exactly as you would like, and the fact that you are using an NSMutableArray becomes an implementation detail. This lets you take advantage of typechecking at compile-time and it lets you change the internal implementation of your Deck class without changing its clients. For instance, if you decided for some reason that an NSMutableDictionary would be a better backing store, you can make all those changes within the implementation of your Deck class without changing any of the code that creates and uses the Deck.
You usually won't need to subclass it, but in any case the suggestions made by Apple are:
Any subclass of NSArray must override the primitive instance methods count
and objectAtIndex:
. These methods must operate on the backing store that you provide for the elements of the collection. For this backing store you can use a static array, a standard NSArray object, or some other data type or mechanism. You may also choose to override, partially or fully, any other NSArray method for which you want to provide an alternative implementation.
Did you actually override count
method? As they say you have to provide your own backing structure to hold array elements, and override suggested methods considering this..
If you're just adding new methods, and using the existing backing store, then a better approach is to add a category to NSArray. Categories are a really powerful part of objective-C - see cocoadev for some samples.
NSMutableArray
already has a - (void)removeObjectsInArray:(NSArray *)otherArray;
You're going to be best off making an NSObject subclass with a mutable array property.
In this particular case, I'd shuffle the array using -sortedArrayUsingComparator:
and make your comparator randomly return NSOrderedAscending
or NSOrderedDescending
.
E.G:
NSArray *originalArray; // wherever you might get this.
NSArray *shuffledArray = [orginalArray sortedArrayUsingComparator:
^(id obj1, id obj2) {
return random() % 2 ? NSOrderedAscending : NSOrderedDescending;
}];