Lee
Lee

Reputation: 5

"-[NSArray count] only defined for abstract class" exception when using an NSArray subclass

I have an NSArray subclass holding objects that I want to sort, but I get an exception with the message

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSArray count]: method only defined for abstract class. Define -[CharacterArray count]!'

I've tried both below ways to do it but I got the above error both times.

[characters sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"strength" ascending:YES]]];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"strength" ascending:YES];
[characters sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

I tried some other ways to do it like below;

NSSortDescriptor *characterSort = [NSSortDescriptor sortDescriptorWithKey:@"strength" ascending:YES selector:@selector(compare:)];

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"strength"  ascending:YES];
NSMutableArray *arr = [[characters sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy];

NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:@"strength" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject:valueDescriptor];
NSArray *sortedArray = [characters sortedArrayUsingDescriptors:descriptors];

but with these methods I get unused variable warning and nothing gets sorted in my original array when I call the method.

#import <Foundation/Foundation.h>
#import "character_array.h"
@implementation CharacterArray
 - (instancetype) init
{
self = [super init];
if (self)
    self.characters = [NSMutableArray array]; return self;
}
- (void) addCharacter: (Character *) charact
 {   NSLog(@"add character method entered");
[self.characters addObject: charact];
}
- (void) printAll
{
int num = 1;
NSLog(@"print all method entered");
for (Character *theCharacter in self.characters)
{    NSLog (@"%d : ", num++);
    [theCharacter printDetails];
}
}
@end

#import <Foundation/Foundation.h>
#import "game_character.h"
@interface CharacterArray : NSMutableArray
@property (strong) NSMutableArray *characters;
- (void) addCharacter: (Character *) charact;
- (void) printAll;
@end

in main under import everything

CharacterArray *characters;

in main method

characters = [CharacterArray alloc];
characters = [characters init];

Upvotes: 0

Views: 1280

Answers (2)

arnas
arnas

Reputation: 31

For anyone that is having this error without using subclass, check if you are not using [[NSArray new] initWith...] instead of [[NSArray alloc] initWith...]

Upvotes: 2

CRD
CRD

Reputation: 53010

Are you sure you are required to create a CharacterArray class and that it should be a subclass of NS(Mutable)Array. Check that the intention is not that you should use an instance characterArray of NS(Mutable)Array, which seems most likely in a "first Objective-C assignment"; or that you are intended to write your class without inheriting from NS(Mutable)Array, less likely but possible.

Least likely is that you are meant to be learning that NS(Mutable)Array cannot be trivially subclassed. Note your error contains:

... only defined for abstract class ...

Objective-C does not really have "abstract" classes, but the system frameworks do use a design termed class clusters which can exhibit some of the same behaviour, and that is what the error message is trying to point out. With a class cluster simple inheritance does not work as expected as the public class, NS(Mutable)Array in this case, does not actually implement the behaviour of many of its methods but relies on other classes in the cluster to do so - and those implementations are not inherited by subclasses of the public class.

Sound complicated? That is why it is surprising it is in a "first assignment".

That said it is not hard to actually subclass NS(Mutable)Array provided you follow the rules, which are to implement a specified set of methods whose implementations are not inherited from NS(Mutable)Array when you subclass. Read the sections "Subclassing Notes" in the NSMutableArray documenatation and NSArray documentation for the list of methods you must implement, which as the error message indicates includes count.

HTH

Upvotes: 1

Related Questions