继承NSArray和NSMutableArray类

3

有关NSArrayNSMutableArray的参考文献提到了可以创建子类,但这只可能通过提供自己的备份存储和方法实现。

  • count

  • objectAtIndex:

对于NSArray,以及

  • insertObject:atIndex:

  • removeObjectAtIndex:

  • addObject:

  • removeLastObject

  • replaceObjectAtIndex:withObject:

对于NSMutableArray。这可能会让程序员误以为简单地通过手段不可能子类化NSArrayNSMutableArray

尽管无法创建利用现有后备存储(即使您不直接访问它们)的“简单”子类,但仍然可以通过一些“解决方法”实现。

因此,当我在寻找仍然能够子类化它们的可能性时,我有一个简单的想法:只需创建子类并使用NSArrayNSMutableArray的实例作为后备存储。

这是它的工作原理:

CSSMutableArray.h

#import <Foundation/Foundation.h>


@interface CSSMutableArray : NSMutableArray {
    NSMutableArray *_backingStore;
}

@end

CSSMutableArray.m

#import "CSSMutableArray.h"


@implementation CSSMutableArray

- (id) init
{
    self = [super init];
    if (self != nil) {
        _backingStore = [NSMutableArray new];
    }
    return self;
}

- (void) dealloc
{
    [_backingStore release];
    _backingStore = nil;
    [super dealloc];
}

#pragma mark NSArray

-(NSUInteger)count
{
    return [_backingStore count];
}

-(id)objectAtIndex:(NSUInteger)index
{   
    return [_backingStore objectAtIndex:index];
}

#pragma mark NSMutableArray

-(void)insertObject:(id)anObject atIndex:(NSUInteger)index
{
    [_backingStore insertObject:anObject atIndex:index];
}

-(void)removeObjectAtIndex:(NSUInteger)index
{
    [_backingStore removeObjectAtIndex:index];
}

-(void)addObject:(id)anObject
{
    [_backingStore addObject:anObject];
}

-(void)removeLastObject
{
    [_backingStore removeLastObject];
}

-(void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject
{   
    [_backingStore replaceObjectAtIndex:index withObject:anObject];
}

@end

如果你想要子类化NSArray,你只需要提供标题为NSArray的部分。现在,你可以从你的“自定义NSArray子类的实现”中进行子类化,并按照你的意愿工作。希望这能有所帮助...平安!Tomen =)

2
#1,这篇文章不是一个问题。 #2,通常你不想子类化NSArrayNSMutableArray的原因是因为它们是类簇 - 更多信息请参见:http://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/ClassCluster.html - Carl Norum
5
谁说过“你不能对NSMutableArray和NSArray进行子类化”?甚至在文档中,苹果也提到了如何做到这一点。 - Ole Begemann
但他们似乎不鼓励这样做。否则,只需将其子类化就不会那么困难。我觉得有明确的代码检查和防止子类化而不提供自定义备份存储。 - Tomen
2
你确实可以子类化NSArray,这在苹果自己的文档中已经说明。从NSArray类参考中可以看到:“通常很少需要子类化NSArray。该类能够很好地完成其设计用途——维护对象的有序集合。但是在某些情况下,自定义的NSArray对象可能会派上用场。” - Brad Larson
此外,请阅读文档中的“子类化注释”部分,其中描述了子类化NSArray所需做的确切步骤。 - Brad Larson
显示剩余3条评论
1个回答

2
继承NSMutableArray并用NSMutableArray作为其后备存储是一个毫无意义且可怕的想法。如果您要子类化像NS(Mutable)Array这样基本的东西,请至少有一个理由这么做。例如,我子类化了NSMutableArray并使用C数组作为其后备存储来使它像循环缓冲区一样工作,因此在前端进行插入和删除与在后端相同快(如果您好奇,可以搜索Google上的CHCircularBuffer)。然而,在大多数情况下,没有子类化的必要。此外,尽管创建一个微不足道的子类可能很简单,但创建一个有用且有意义的子类则不是一件微不足道的事情。

这是一个很好的例子,大多数情况下不需要对NSMutableArray进行子类化。根据文档,在任一端添加或删除对象都需要恒定的时间(请参见https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Collections/Articles/Arrays.html#//apple_ref/doc/uid/20000132-BBCCJBIF)。 - Tom
1
我推荐阅读Bartosz Ciechanowski的《Exposing NSMutableArray》(http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/)。这很相关。 - Douglas Hill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接