I have subclassed NSMutableArray as follows:
Base Class:
@interface MyBaseMutableArray : NSMutableArray {
// Database variables
NSString * databaseName;
NSString * databasePath;
}
@property (nonatomic, retain) NSString * databasePath;
- (id)initWithContentsOfSQLiteDB:(NSString *)dbTable;
-(void) checkAndCreateDatabase;
-(void) readFromDatabase;
@end
Subclass:
@interface IngredientsMutableArray : MyBaseMutableArray
{
}
-(void) readFromDatabase;
@end
When I create an IngredientsMutableArray I do the following:
IngredientsMutableArray * i = [[IngredientsMutableArray alloc]
init开发者_如何转开发WithContentsOfSQLiteDB:@"MyIngredientsDB.sql"];
BUT, when I try to perform the [self addObject:ingred] I throw an exception as follows:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSArray count]: method only defined for abstract class. Define -[IngredientsMutableArray count]!'
I believe I am not initializing the NSMutableArray correctly. I was going to us initWithCapaciity, but I do not know the count before the SQL call. I think I am overlooking something obvious, but being somewhat of a newbie to Objective C I am slightly befuddled.
Any help is appreciated.
According to the documentation you need to:
Methods to Override
NSMutableArray‘s methods are conceptually based on these primitive methods:
insertObject:atIndex: removeObjectAtIndex: addObject: removeLastObject replaceObjectAtIndex:withObject:
In a subclass, you must override all these methods, although you can implement the required functionality using just the first two (however this is likely to be inefficient). You must also override the primitive methods of the NSArray class.
But the real answer is that you don't really want to be subclass it. There are two options:
- Use a category
- Create a new class that has an
NSArray
as a member variable
I think I'd go for option two in this case.
In general, you tend to subclass system classes much less often than you would in C# or Java.
You don't want to subclass NSArray or NSMutableArray. It's a class cluster. From the NSArray docs:
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.
As recommended in those same docs, try a category or composition, rather than inheritance.
NSMutableArray
is a class cluster – the NSMutableArray
class just defines the interface and when you instantiate it, you get an object of a different, private type back. This makes NSMutableArray
and other class clusters hard to subclass, you’d be much better off with composition. Read this Friday Q&A with Mike Ash if you are interested in the [gory] details.
精彩评论