如何扩展NSArray?

Rog*_*son 6 objective-c extend nsarray ios

这是我的尝试:

H文件:

@interface Strings : NSArray
@end
Run Code Online (Sandbox Code Playgroud)

M文件:

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

我跑的时候得到这个:

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

这就是我所做的:

H文件:

@interface Strings : NSObject
+ (NSArray*) getStrings;
@end
Run Code Online (Sandbox Code Playgroud)

M文件:

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

rob*_*off 8

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

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

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


Dar*_*ust 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;
}
Run Code Online (Sandbox Code Playgroud)

但正如我刚才所说,它只是不那么容易.你会再次得到同样的例外.所以你应该简单地避免从中衍生出来NSArray.

可以做的是添加一个类别以向所有NSArray实例添加方法.