NSMutableArray addObject: - [__ NSArrayI addObject:]:发送到实例的无法识别的选择器

时间:2010-07-10 17:17:20

标签: iphone nsmutablearray

我已经尝试从周日初始化我的NSMutableArray 100种方式,并且NOTHING正在为我工​​作。我尝试将它设置为等于新分配和初始化的NSMutableArray,只是分配,自己初始化变量,我能想到的每个组合,并且总是相同的结果。

以下是代码:

Object.h

NSMutableArray *array;

@property (copy) NSMutableArray *array;

Object.m

@synthesize array;

if ( self.array ) {
    [self.array addObject:anObject];
}
else {
    self.array = [NSMutableArray arrayWithObjects:anObject, nil];
}

注意:在调试中,“anObject”在执行时不是nil ......

我已经测试了anObject,它是初始化的工作正常,但是当我尝试addObject:to self.array时,我不断收到以下错误。

  

2010-07-10 11:52:55.499 MyApp [4347:1807] - [__ NSArrayI addObject:]:无法识别的选择器发送到实例0x184480

     

2010-07-10 11:52:55.508 MyApp [4347:1807] ***因未捕获的异常而终止应用   'NSInvalidArgumentException',原因:' - [__ NSArrayI addObject:]:无法识别的选择器发送到实例0x184480'

有谁知道出了什么问题?

9 个答案:

答案 0 :(得分:83)

@property (copy)的合成setter向数组发送copy消息,从而产生不可变副本。

你别无选择,只能在这里实现setter,如Objective-C指南中的detailed

答案 1 :(得分:73)

当我在阅读我的帖子时,我想到了一个想法,我回答了自己的问题。这个决议很模糊,我决定继续,创建帖子并自己回答(所以任何其他新手,比如我自己,都不会挂断)。

我的错误在......

@property (copy) NSMutableArray *array;

应该是......

@property (retain) NSMutableArray *array;

错误不是以我执行代码的方式发生的,而是anObject试图“复制”NSMutableArray数组的方式。

众所周知......

mutableArray = [mutableArray copy];

并不总是(或根据我的经验)等于......

mutableArray = [mutableArray mutableCopy];

这是我的问题的根源。通过简单地将@property从(复制)切换到(保留),我解决了我的问题。

答案 2 :(得分:11)

我想向Georg Fritzsche致敬。我最终需要使用(复制)而不是(保留),如果没有他的输入,我不知道该怎么做。

//@property (copy) NSMutableArray *array;
@property (nonatomic, copy) NSMutableArray *array; //overridden method is non-atomic as it is coded and should be reflected here.

如果您希望在可变对象上使用(复制),则必须覆盖“setter”方法,如下所示...

- (void)setArray:(NSArray *)newArray {

    if ( array != newArray ) { 
        [array release];
        array = [newArray mutableCopy];
//      [array retain]; // unnecessary as noted by Georg Fritzsche
    }

    return;
}

注意:你会得到一个编译器警告:不兼容的Objective-C类型初始化'struct NSArray *',期望'struct NSMutableArray *'我选择将newArray参数声明为(NSArray *),因为你有灵活性将任何数组传递并正确复制到您的(NSMutableArray *)变量。如果您希望将newArray参数声明为(NSMutableArray *),您仍需要保留mutableCopy方法以获得所需的结果。

欢呼乔治! ž@ķ!

答案 3 :(得分:3)

我得到了同样的错误,即使我的属性很强(使用ARC)并且我使用NSMutableArray分配了数组。

发生的事情是我正在归档可变数组(因为它包含自定义对象)以供将来使用,在解码时,它会返回一个不可变的副本。

希望它可以帮助那里的任何人。

答案 4 :(得分:3)

有一些索引(在其他地方的数据数组中)并希望按数字顺序排列(有充分理由)。崩溃直到最后添加mutableCopy。完全不解,直到我回忆起使用 Objective-C literal @ []返回一个不可变数组

NSMutableArray *a = [@[@(self.indexA), @(self.indexB)] mutableCopy];
NSLog(@"%@", a);
[indexArray sortUsingComparator: ^(NSNumber *obj1, NSNumber *obj2) {
    return [obj1 compare:obj2];
}];
NSLog(@"%@", a);

Thanx,Zak!

答案 5 :(得分:0)

由于我犯了一个错字,我被这个例外所困扰,也许它会拯救一个人5分钟。他们的时间:

我写道:

NSMutableArray *names = [NSArray array];

而不是:

NSMutableArray *names = [NSMutableArray array];

编译器没有问题,因为NSMutableArray也是一个NSArray,但在尝试添加对象时它会崩溃。

答案 6 :(得分:0)

由于尝试将对象添加到实际指向NSArray对象的NSMutableArray类型而导致错误。下面的一些演示代码中显示了这种类型的场景:

NSString *test = @"test";
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
[mutableArray addObject:test];
NSArray *immutableArray = [[NSArray alloc] init];
mutableArray = immutableArray;
[mutableArray addObject:test]; // Exception: unrecognized selector

从上面的代码中,很容易看到子类类型被分配给超类类型。例如,在Java中,这会立即被标记为错误(类型之间的转换错误),并且问题很快得到解决。为了公平对待Objective-C,在尝试执行不兼容的赋值时会给出警告,但是,这有时似乎不够,并且结果对于开发人员来说可能是一个真正的痛苦。幸运的是,这一次,不是我自己承受了大部分痛苦:P

答案 7 :(得分:0)

我有类似的错误说法:无法识别的选择器发送到NSMutable数组的实例。经过很多事情之后,我发现我将可变数组用作属性,

@property (assign, nonatomic) NSMutableArray *myMutableArray;

在复制粘贴时没有注意,这是导致问题的原因。

我们将其更改为强类型的解决方案(您可以根据需要将其更改为其他类型,例如强/弱等。)所以我的解决方案是:

@property (strong, nonatomic) NSMutableArray *myMutableArray;

因此,在复制粘贴时要小心!请检查一次。

答案 8 :(得分:-3)

如果数组中的某个对象为null,则会发生此异常。