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

Zak*_*Zak 67 iphone nsmutablearray

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

这是代码:

Object.h

NSMutableArray *array;

@property (copy) NSMutableArray *array;
Run Code Online (Sandbox Code Playgroud)

Object.m

@synthesize array;

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

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

我已经测试了anObject,它的初始化工作正常,但是当我尝试addObject: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'

有谁知道出了什么问题?

Geo*_*che 83

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

你别无选择,只能在这里实现setter,详见 Objective-C指南.


Zak*_*Zak 73

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

我的错误在......

@property (copy) NSMutableArray *array;
Run Code Online (Sandbox Code Playgroud)

应该是......

@property (retain) NSMutableArray *array;
Run Code Online (Sandbox Code Playgroud)

错误不是以我执行代码的方式发生的,而是在anObject试图"复制"NSMutableArray数组的方式中发生的.

众所周知......

mutableArray = [mutableArray copy];
Run Code Online (Sandbox Code Playgroud)

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

mutableArray = [mutableArray mutableCopy];
Run Code Online (Sandbox Code Playgroud)

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


Zak*_*Zak 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.
Run Code Online (Sandbox Code Playgroud)

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

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

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

    return;
}
Run Code Online (Sandbox Code Playgroud)

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

欢呼乔治!ž@ķ!