向NSArray添加类别

时间:2009-12-28 15:31:19

标签: iphone objective-c categories

我在NSArray中添加了一个带有辅助方法进行排序的类别。我的单元测试全部通过,但是当在模拟器中运行应用程序时,它会爆炸。这可能是因为NSMutableArray / NSCFArray class cluster stuff?

这是错误: 'NSInvalidArgumentException',原因:'*** - [NSCFArray sortBySequenceAsc]:无法识别的选择器发送到实例0x489c1f0'

无论如何,向NSArray和NSMutableArray添加类别的正确方法是什么?

@interface NSArray (Util) 
- (NSArray *)sortBySequenceAsc;
@end 

@implementation NSArray (Util)
- (NSArray *)sortBySequenceAsc {
    //my custom sort code here
}
@end

5 个答案:

答案 0 :(得分:9)

我在NSArray多次使用类别没有任何问题,所以我猜你的问题出在其他地方(因为你的类别看起来是正确的)。

由于您收到“无法识别的选择器”错误,这意味着运行时不知道您的类别,这意味着它没有链接到您的二进制文件。我会检查并确保您的类别的.m文件包含在相应的目标中,清理并再次构建。

编辑:例如,this blog post显示如何为NSArray创建一个类别,用于创建原始数组的随机副本。

编辑#2:Apple关于类别的文档使用了扩展NSArray功能的具体示例,因此我发现很难相信“推荐”的方法是将数组包装在辅助对象中。 Citation (search the page for the five "NSArray" references)

答案 1 :(得分:2)

推荐的方法是创建一个包含NSArray的新对象。在NSArray下面,苹果并没有告诉我们很多关于它的事情;当您添加新方法时,您无法访问这些内容,从而导致错误。

基本上,这样做:

@interface MySortingArray : NSObject {
     NSArray *theArray
}

- (int)count;
- (NSArray *)sortBySequenceAsc;

@end

@implementation MySortingArray

- (int)count {
    return [theArray count];
}

- (NSArray *)sortBySequenceAsc {
   // your code
}

@end

答案 2 :(得分:2)

即使参加派对已经很晚了,我还是想加入一些东西。

当我制作返回NSArray的方法时,有时候我很懒。我实际上返回了我在方法中构建的NSMutableArray。我想,“什么可能出错?”。我使用它作为模式来返回我正在使用的可变实例的不可变版本。

除了这是出错的地方。显然,苹果懒洋洋地从一个接口返回一个NSMutableArray,该接口声明它是一个NSArray。如果你在NSArray上添加一个类别,它将不会被添加到NSMutableArray。因为NSMutableArray是NSArray,但NSArray不是NSMutableArray。

答案 3 :(得分:1)

将一个排序类别放在NSArray上是一个坏主意...这应该是不可修改的......除非你打算提取所有元素并返回,否则这种类型的功能是NSMutableArray的范围一个完全不同的NSArray实例,这是令人困惑的行为。

答案 4 :(得分:0)

确实,这是因为类集群。您在NSArray上创建了一个类别,但是您在没有方法的私有类__NSCFArray上调用该方法。我找到了一种解决方法:使用现有数组显式创建新的NSArray。新数组的类(对象的isa指针)将指向类别所在的正确类。

所以,而不是这样做:

NSArray *array = [someObject someMethod];
// "array" may be a private class with the same methods as "NSArray", but not yours.

[array yourMethod];

这样做:

NSArray *array = [NSArray arrayWithArray: [someObject someMethod]];
// "array" is now explicitly a "NSArray"

[array yourMethod];

它有效,但我希望仍然如此。这是非常不可预测的。这就是我在这里使用开源代码创建自己的数组实现的原因。我省略了我不需要的方法,并添加了我可能需要的新方法(如shuffle)。我现在正在彻底测试它。