Why doesn’t my NSMutableArray subclass work as expected?

[亡魂溺海] 提交于 2019-12-13 12:24:13

问题


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]
    initWithContentsOfSQLiteDB:@"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.


回答1:


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:

  1. Use a category
  2. 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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/5937870/why-doesn-t-my-nsmutablearray-subclass-work-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!