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消息转发将除自定义行为之外的所有内容转发到该类.
这是由于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网格).