【问题标题】:Inheritance Issues in Objective CObjective C 中的继承问题
【发布时间】:2009-08-12 19:35:28
【问题描述】:

我创建了一个“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

这是 .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

这是控制台上显示的内容:

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

【问题讨论】:

    标签: iphone objective-c xcode inheritance


    【解决方案1】:

    简短的回答:不要创建 NSArray 的子类。最好在 NSArray 上创建一个类别,或者创建一个 NSObject 子类,其中包含一个与您交谈的 NSArray ivar。

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

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

    【讨论】:

    • +1 我要补充一点,将NSArray 包装在NSObject 的子类中的第一个示例称为复合类
    【解决方案2】:

    这是由于 Foundation 中用于集合类的“类集群”的性质。 看: Class Clusters

    基本上,NSMutableArray 为“可变数组”定义了一个公共接口,但它不是您在初始化时使用的实际类。所以 'initWithCapacity:' 被定义了,但没有在 NSMutableArray 中实现。如果你运行:

    NSMutableArary *foo = [[NSMutableArray alloc] init];
    NSLog(@"%@", [foo className]);
    

    您将打印“_NSCFArray”,它是 NSMutableArray(和 NSArray)的具体子类。为了解决这个问题,我将有一个实例变量,它是一个 NSMutableArray,或者实现具有适当含义的 'initWithCapacity:'(例如容量为 '3' 表示 3x3 网格)。

    【讨论】:

      【解决方案3】:

      好的,我从this question找到了答案

      虽然问题不同,但答案是相同的,那就是由于 NSArray(以及因此 NSMutableArray)的设置,如果不自己实现方法,就不能对其进行子类化。

      所以我想我会让 SDMutableGrid 有一个 NSMutableArray 变量,而不是实际上是一个 NSMutableArray。

      【讨论】:

      • 检查所有答案,这些都是一些快速响应。
      【解决方案4】:

      你的问题是你没有实现需要实现的 NSMutableArray 超类的抽象方法,它说 -[NSMutableArray initWithCapacity:]:仅为抽象类定义的方法。定义 -[SDMutableGrid initWithCapacity:]!' 2009-08-12 15:27:02.080 翻转开关[1756:20b]

      所以你需要在你的子类中定义 initWithCapacity,我建议不要扩展 NSMutableArray,没有必要,只需创建一个包含可变数组的类。

      【讨论】:

        猜你喜欢
        • 2011-07-26
        • 2013-09-26
        • 1970-01-01
        • 1970-01-01
        • 2012-03-10
        • 2012-11-11
        • 1970-01-01
        • 1970-01-01
        • 2012-05-11
        相关资源
        最近更新 更多