为什么我的NSMutableArray子类不能按预期工作?

时间:2011-05-09 13:55:33

标签: objective-c nsmutablearray

我已经将NSMutableArray子类化如下:

基类:

@interface MyBaseMutableArray : NSMutableArray {
    // Database variables
    NSString * databaseName;
    NSString * databasePath;
}

@property (nonatomic, retain) NSString * databasePath;

- (id)initWithContentsOfSQLiteDB:(NSString *)dbTable;
-(void) checkAndCreateDatabase;
-(void) readFromDatabase;

@end

子类:

@interface IngredientsMutableArray : MyBaseMutableArray
{

}

-(void) readFromDatabase;

@end

当我创建一个IngredientsMutableArray时,我会执行以下操作:

IngredientsMutableArray * i  = [[IngredientsMutableArray alloc]
    initWithContentsOfSQLiteDB:@"MyIngredientsDB.sql"];

但是,当我尝试执行[self addObject:ingred]时,我抛出一个异常,如下所示:

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

我相信我没有正确初始化NSMutableArray。我打算给我们initWithCapaciity,但我不知道SQL调用之前的计数。我想我忽略了一些显而易见的事情,但对于Objective C而言,我有点像新手。我有点迷惑。

感谢任何帮助。

3 个答案:

答案 0 :(得分:25)

According to the documentation您需要:

  

覆盖方法

     

NSMutableArray的方法是   概念上基于这些原始   方法:

insertObject:atIndex:

removeObjectAtIndex:

addObject:

removeLastObject

replaceObjectAtIndex:withObject:
     

在子类中,您必须覆盖所有   这些方法虽然可以   实现所需的功能   只使用前两个(但是这个   可能是效率低下的)。你必须   也覆盖原始方法   NSArray课程。

真正的答案是你真的不想成为它的子类。有两种选择:

  1. 使用类别
  2. 创建一个具有NSArray作为成员变量的新类
  3. 我认为在这种情况下我会选择第二种选择。

    通常,您倾向于将系统类子类化为比C#或Java更少的子类。

答案 1 :(得分:4)

您不希望继承NSArray或NSMutableArray。这是一个类集群。来自NSArray docs

  

NSArray的任何子类都必须覆盖   原始实例方法计数   和objectAtIndex:。这些方法必须   在您的后备存储上运行   提供的元素   采集。对于这个支持商店你   可以使用静态数组,标准   NSArray对象或其他一些数据   类型或机制。你也可以选择   部分或全部覆盖任何   你的其他NSArray方法   想提供替代方案   实施

根据这些文档中的建议,尝试一个类别或组合,而不是继承。

答案 2 :(得分:0)

NSMutableArrayclass cluster - NSMutableArray类只定义接口,当您实例化它时,您将得到一个不同的私有类型的对象。这使得NSMutableArray和其他类集群难以进行子类化,你的组合会更好。如果您对[gory]详细信息感兴趣,请阅读此Friday Q&A with Mike Ash