目标C中的继承问题

Joe*_*Joe 6 iphone xcode inheritance objective-c

我创建了一个"SDMutableGrid"类,以便我可以使用网格.它只是NSMutableArray的一个子节点,它包含一个数字,用于等于网格中行数的数组.

目前,该程序在它真正启动之前退出并且它似乎是因为为NSMutableArray定义的方法不知何故不适用于SDMutableGrid,任何人都知道为什么?

这是.h:

#import <Foundation/Foundation.h>
#import "SDDimensions.h"

@interface SDMutableGrid : NSMutableArray {
SDDimensions dimensions;
}

@property (nonatomic) SDDimensions dimensions;

- (id)initWithDimensions:(SDDimensions)newDimensions;
- (void)addObject:(id)anObject toRow:(NSUInteger)row;

@end
Run Code Online (Sandbox Code Playgroud)

这是.m:

#import "SDMutableGrid.h"

@implementation SDMutableGrid

@synthesize dimensions;

- (void)setDimensions:(SDDimensions)newDimensions {
if (newDimensions.width < dimensions.width) {
    NSMutableArray *anArray;
    NSRange aRange = NSMakeRange(newDimensions.width, dimensions.width - newDimensions.width);
    for (NSUInteger i = 0; i < MIN(dimensions.height,newDimensions.height); i++) {
        anArray = [self objectAtIndex:i];
        [anArray removeObjectsInRange:aRange];
    }
}
dimensions.width = newDimensions.width;
if (newDimensions.height > dimensions.height) {
    for (NSUInteger i = dimensions.height; i < newDimensions.height; i++) {
        [self addObject:[[NSMutableArray alloc] initWithCapacity:dimensions.width]];
    }
} else if (newDimensions.height < dimensions.height) {
    [self removeObjectsInRange:NSMakeRange(newDimensions.height, dimensions.height - newDimensions.height)];
}
dimensions.height = newDimensions.height;
}

- (id)initWithDimensions:(SDDimensions)newDimensions {
if (self = [super initWithCapacity:newDimensions.height]) {
    NSMutableArray *anArray;
    for (NSUInteger i = 0; i < newDimensions.height; i++) {
        anArray = [[NSMutableArray alloc] initWithCapacity:newDimensions.width];
        NSLog(@"Got this far");
        [self addObject:anArray];
        NSLog(@"woot");
        [anArray release];
    }
    NSLog(@"Finished Initializing grid");
}
return self;
}

- (void)addObject:(id)anObject toRow:(NSUInteger)row {
    [[self objectAtIndex:row] addObject:anObject];
}

@end
Run Code Online (Sandbox Code Playgroud)

以下是控制台上出现的内容:

2009-08-12 15:27:02.076 Flipswitch [1756:20b] 因未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:' - [NSMutableArray initWithCapacity:]:仅为抽象类定义的方法.定义 - [SDMutableGrid initWithCapacity:]!' 2009-08-12 15:27:02.080 Flipswitch [1756:20b] Stack:(807902715,2536648251,808283725,808264737,13690,11018,10185,814713539,814750709,814739251,814722434,814748641,839148405,807687520,807683624,814715661 ,814752238,10052,9906)

Chu*_*uck 37

简短而简单的答案:不要创建NSArray的子​​类.最好在NSArray上创建一个类别,或者创建一个NSObject子类,它具有与之交谈的NSArray ivar.

长期的技术答案:NSArray是一个类集群.这意味着它实际上不是一个类,而是在NSArray抽象类接口下运行的许多类,每个类都以不同的方式实现(例如,一个实现小型数组,另一个实现大型数组等).要创建类集群的子类,您必须实现您继承的抽象类的所有原始方法,管理您自己的存储,并基本上重新实现您希望通过子类化免费获得的所有内容.

更简单地说,如果您不需要额外的ivars,您可以创建一个类别.如果您希望对象的行为类似于具有其他状态的数组,则可以创建一个具有NSArray的类,并使用Objective-C消息转发将除自定义行为之外的所有内容转发到该类.


bob*_*vil 7

这是由于Foundation中用于集合类的"Class Clusters"的性质.请参阅: 类集群

基本上,NSMutableArray定义了"可变数组"的公共接口,但它不是初始化时使用的实际类.因此'initWithCapacity:'已定义,但未在NSMutableArray中实现.如果您运行:

NSMutableArary *foo = [[NSMutableArray alloc] init];
NSLog(@"%@", [foo className]);
Run Code Online (Sandbox Code Playgroud)

你将打印"_NSCFArray",这是NSMutableArray(和NSArray)的具体子类.要解决这个问题,我会有一个NSMutableArray实例变量,或者实现具有合适含义的'initWithCapacity:'(例如'3'的容量意味着3x3网格).