我如何扩展一个NSArray?

这是我的尝试:

H文件:

@interface Strings : NSArray @end 

M文件:

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

当我运行我得到这个:

'NSInvalidArgumentException',reason:' * – [NSArray initWithObjects:count:]:只为抽象类定义的方法。 定义 – [stringinitWithObjects:count:]!

这是我所做的:

H文件:

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

M文件:

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

NSArray是一个类集群 (链接到苹果的文档) 。 这意味着当你尝试创build一个NSArray ,系统会创build一些NSArray私有子类。 NSArray类只是定义一个接口; NSArray子类提供接口的实现。

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

可变参数initWithObjects:方法的NSArray实现只是initWithObjects:count:一个包装,所以你不必实现initWithObjects:

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

请记住,NSArray是类集群的公共接口,这对于你的子类是什么。 NSArray的原始方法不包含任何指定的初始值设定项。 这意味着您必须为您的子类提供存储并实现直接作用于该存储的原始方法。

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

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

最后但并非最不重要的是,你将会有初始化错误。 你将需要打电话给super

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

但正如我刚才所说,这并不容易。 你会再次得到同样的exception。 所以你应该避免从NSArray派生。

可以做的就是添加一个类来为所有的NSArray实例添加方法。

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

请参阅Objective C – inheritanceNSArray以获取更多想法。

也许

 self = [super initWithObjects:...]; 

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

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