简体   繁体   English

Objective C - 对NSArray进行子类化

[英]Objective C - Subclassing NSArray

I am trying to subclass NSArray , but it crashes the app when trying to access the count method. 我试图NSArray ,但它在尝试访问count方法时崩溃了应用程序。 I know that NSArray is a class cluster . 我知道NSArray是一个类集群

  • But what does this mean? 但是,这是什么意思?
  • Is there a work around to be able to subclass an NSArray? 有没有可以继承NSArray的工作?

I know that I can simply subclass NSObject and have my array as an instance variable but I would rather subclass NSArray . 我知道我可以简单地NSObject并将我的数组作为实例变量,但我宁愿NSArray

EDIT: Reason: I am creating a card game, I have a class Deck which should subclass NSMutableArray to have a couple of extra methods ( -shuffle , -removeObjects: , -renew , etc), and I think it will look cleaner to subclass NSArray rather than having a var. 编辑:原因:我正在创建一个纸牌游戏,我有一个类Deck ,它应该将NSMutableArray子类-shuffle一些额外的方法( -shuffle-removeObjects: ,- -renew等),我认为它对于子类看起来更干净NSArray而不是var。

The problem with adding a category on a class like this is that all instances of the class will inherit the additional methods. 在类这样的类上添加类别的问题是该类的所有实例都将继承其他方法。 That's both unnecessary (since not every array needs to be able to be shuffled, etc.) and dangerous (because you can't benefit from typechecking to be sure the NSArray you're currently referring to is really one that was expected to be shuffled). 这既不必要(因为不是每个阵列都需要能够被洗牌等)而且很危险(因为你不能从类型检查中受益,以确保你当前所指的NSArray确实是一个预计会被洗牌的人)。

An alternative would be to create your own Deck class that has an NSMutableArray as an instance variable. 另一种方法是创建自己的Deck类,它具有NSMutableArray作为实例变量。 There you can define actions on your deck exactly as you would like, and the fact that you are using an NSMutableArray becomes an implementation detail. 在那里,您可以完全按照自己的意愿在甲板上定义操作,并且您使用NSMutableArray的事实将成为实现细节。 This lets you take advantage of typechecking at compile-time and it lets you change the internal implementation of your Deck class without changing its clients. 这使您可以在编译时利用类型检查,它允许您在不更改其客户端的情况下更改Deck类的内部实现。 For instance, if you decided for some reason that an NSMutableDictionary would be a better backing store, you can make all those changes within the implementation of your Deck class without changing any of the code that creates and uses the Deck. 例如,如果您出于某种原因决定NSMutableDictionary将是更好的后备存储,那么您可以在Deck类的实现中进行所有这些更改,而无需更改任何创建和使用Deck的代码。

You usually won't need to subclass it, but in any case the suggestions made by Apple are: 您通常不需要对其进行子类化,但无论如何,Apple提出的建议是:

Any subclass of NSArray must override the primitive instance methods count and objectAtIndex: . NSArray的任何子类都必须覆盖原始实例方法countobjectAtIndex: . These methods must operate on the backing store that you provide for the elements of the collection. 这些方法必须在您为集合元素提供的后备存储上运行。 For this backing store you can use a static array, a standard NSArray object, or some other data type or mechanism. 对于此后备存储,您可以使用静态数组,标准NSArray对象或某些其他数据类型或机制。 You may also choose to override, partially or fully, any other NSArray method for which you want to provide an alternative implementation. 您还可以选择部分或完全覆盖要为其提供替代实现的任何其他NSArray方法。

Did you actually override count method? 你真的覆盖了count方法吗? As they say you have to provide your own backing structure to hold array elements, and override suggested methods considering this.. 正如他们所说,你必须提供自己的支持结构来保存数组元素,并考虑到这一点覆盖建议的方法。

If you're just adding new methods, and using the existing backing store, then a better approach is to add a category to NSArray. 如果您只是添加新方法,并使用现有的后备存储,那么更好的方法是向NSArray添加一个类别。 Categories are a really powerful part of objective-C - see cocoadev for some samples. 类别是Objective-C的一个非常强大的部分 - 有些样本请参阅cocoadev

NSMutableArray already has a - (void)removeObjectsInArray:(NSArray *)otherArray; NSMutableArray已经有一个- (void)removeObjectsInArray:(NSArray *)otherArray; You're going to be best off making an NSObject subclass with a mutable array property. 你最好用一个可变数组属性创建一个NSObject子类。

In this particular case, I'd shuffle the array using - sortedArrayUsingComparator: and make your comparator randomly return NSOrderedAscending or NSOrderedDescending . 在这种特殊情况下,我使用 - sortedArrayUsingComparator:对数组进行洗牌,并使比较器随机返回NSOrderedAscendingNSOrderedDescending

EG: 例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM