如何扩展NSArray?

时间:2012-01-22 20:45:38

标签: objective-c ios nsarray extend

这是我的尝试:

H档:

@interface Strings : NSArray
@end

M档案:

@implementation Strings
- (id) init
{
    [self initWithObjects:
     @"One.",
     nil];
    return self;
}
@end

当我跑步时,我得到了这个:

'NSInvalidArgumentException',原因:' * - [NSArray initWithObjects:count:]:仅为抽象类定义的方法。定义 - [Strings initWithObjects:count:]!'

这就是我所做的:

H档:

@interface Strings : NSObject
+ (NSArray*) getStrings;
@end

M档案:

@implementation Strings
+ (NSArray*) getStrings
{
    NSArray* strings = [[NSArray alloc] initWithObjects:
     @"One.",
     nil];
    return strings;
}
@end

5 个答案:

答案 0 :(得分:8)

NSArrayclass cluster (link to Apple's documentation)。这意味着当您尝试创建NSArray时,系统会创建一些NSArray的私有子类。 NSArray类只定义了一个接口; NSArray的子类提供了接口的实现。

您可以编写自己的NSArray子类,但必须为数组中的对象提供自己的存储。您必须自己初始化该存储。错误消息告诉您,您需要覆盖子类中的initWithObjects:count:。您的覆盖需要将对象放入您作为类实现的一部分分配的任何存储中。

可变参数NSArray方法的initWithObjects:实现只是initWithObjects:count:的包装,因此您无需实现initWithObjects:

答案 1 :(得分:5)

NSArray派生是你应该避免的。来自文档:

  

请记住,NSArray是类集群的公共接口,以及它对您的子类的要求。 NSArray的原始方法不包括任何指定的初始化器。这意味着您必须为子类提供存储并实现直接作用于该存储的基本方法。

这意味着当您初始化数组时,您不会获得NSArray的实例。您将获得一个完全不同的类的实例,它只具有相同的接口。这就是为什么子类化不能像你认为的那样工作的原因:你必须自己完全实现存储。这就是文档进一步说明的原因:

  

NSArray的任何子类都必须覆盖原始实例方法count和objectAtIndex:。这些方法必须在您为集合元素提供的后备存储上运行。对于此后备存储,您可以使用静态数组,标准NSArray对象或某些其他数据类型或机制。您也可以选择部分或完全覆盖要为其提供替代实现的任何其他NSArray方法。

最后但并非最不重要的是,无论如何你都会遇到初始化错误。您需要致电super

- (id)init
{
    self = [super initWithObjects:@"One", @"Two", nil];
    if (!self) return nil;

    return self;
}

但正如我刚才所说,它只是不那么容易。你会再次得到同样的例外。因此,您应该避免从NSArray派生。

可以做的是添加一个类别,以便为所有NSArray个实例添加方法。

答案 2 :(得分:2)

NSArray不支持以这种方式进行子类化。但是,您可以添加一个类别,尽管这并不是普遍推荐的。

有关更多想法,请参阅Objective C - Subclassing NSArray

答案 3 :(得分:1)

也许

self = [super initWithObjects:...];

答案 4 :(得分:1)

你需要指定self,并调用你的超类'init方法。

if (self = [super initWithObjects:...]) {
   ...
}

return self;