【问题标题】:Objective C - Subclassing NSArrayObjective C - 子类化 NSArray
【发布时间】:2010-12-04 01:35:22
【问题描述】:

我正在尝试子类化 NSArray,但在尝试访问 count 方法时它会使应用程序崩溃。我知道NSArray 是一个类簇

  • 但这意味着什么?
  • 是否有变通方法可以将 NSArray 子类化?

我知道我可以简单地继承 NSObject 并将我的数组作为实例变量,但我宁愿继承 NSArray

编辑: 原因: 我正在创建一个纸牌游戏,我有一个 Deck 类,它应该是 NSMutableArray 的子类,有几个额外的方法(-shuffle-removeObjects:-renew 等),我认为它看起来会更干净继承 NSArray 而不是拥有一个 var。

【问题讨论】:

  • 为什么需要子类化?
  • 我可能只是创建一个类别来添加额外的方法而不是子类化:(
  • 类别+1。为此子类化 NS*Array 是严重的过度杀伤,Objective-C 类别完全没有必要。

标签: objective-c cocoa nsarray subclass class-cluster


【解决方案1】:

像这样在类上添加类别的问题是该类的所有实例都将继承附加方法。这既是不必要的(因为不是每个数组都需要能够被洗牌等)而且很危险(因为你不能从类型检查中受益,以确保你当前所指的 NSArray 确实是一个预期被洗牌的数组)。

另一种方法是创建您自己的 Deck 类,该类将 NSMutableArray 作为实例变量。在那里,您可以完全按照您的意愿在您的卡组上定义操作,并且您使用 NSMutableArray 的事实成为实现细节。这使您可以在编译时利用类型检查,并且可以在不更改其客户端的情况下更改 Deck 类的内部实现。例如,如果您出于某种原因决定将 NSMutableDictionary 用作更好的后备存储,则可以在 Deck 类的实现中进行所有这些更改,而无需更改任何创建和使用 Deck 的代码。

【讨论】:

  • 我不认为他暗示有技术开销,他只是说每个实例都获得了您的“子类”的功能,无论它是否相关。例如,意外地在非预期对象的 NSArray 上调用“-shuffle”可能会或可能不会起作用,并且不应被允许。
【解决方案2】:

您通常不需要对其进行子类化,但无论如何,Apple 提出的建议是:

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

你真的重写了countmethod吗?正如他们所说,您必须提供自己的支持结构来保存数组元素,并考虑到这一点覆盖建议的方法..

【讨论】:

  • mm 我尝试了覆盖计数,并调用 [super count] 但这不起作用
  • 您应该提供自己的支持数组,而不是依赖 NSArray 已经提供的数组,否则您可以只使用 NSArray 作为实例变量并将原始 count 映射到内部 NSArray 计数
【解决方案3】:

如果您只是添加新方法并使用现有的后备存储,那么更好的方法是将类别添加到 NSArray。类别是 Objective-C 的一个非常强大的部分 - 请参阅 cocoadev 获取一些示例。

【讨论】:

  • 向 NSArray 添加类别以添加特定于应用程序的功能通常是个坏主意。
【解决方案4】:

NSMutableArray 已经有一个- (void)removeObjectsInArray:(NSArray *)otherArray; 最好创建一个带有可变数组属性的 NSObject 子类。

【讨论】:

    【解决方案5】:

    在这种特殊情况下,我会使用 -sortedArrayUsingComparator: 对数组进行洗牌,并使您的比较器随机返回 NSOrderedAscendingNSOrderedDescending

    例如:

    NSArray *originalArray; // wherever you might get this.
    NSArray *shuffledArray = [orginalArray sortedArrayUsingComparator:
        ^(id obj1, id obj2) { 
         return random() %  2 ? NSOrderedAscending : NSOrderedDescending;
         }];
    

    【讨论】:

    • 很确定这不会起作用,因为它永远不会处于稳定状态。
    • 实际上,它确实有效。改组包含 @"A"..@"J" 的数组最终会调用比较器块 19 次。
    • 错了。排序算法需要一个总顺序,即 a > b、a
    猜你喜欢
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    相关资源
    最近更新 更多