NSMutableArray методы addObject: -[NSArrayI методы addObject:]: непризнанной селектор послал экземпляр


Я попытался инициализировать мой NSMutableArray 100 способов с воскресенья, и ничего не работает для меня. Я попытался установить его равным недавно выделенному и инициализированному NSMutableArray, просто выделяя, инициализируя переменную сама по себе, каждую комбинацию, о которой я мог думать, и всегда один и тот же результат.

вот код:

8 66

8 ответов:

синтезированный сеттер для @property (copy) передает copy сообщение в массив, что приводит к неизменяемой копии.

у вас нет выбора, кроме реализации сеттера самостоятельно здесь, как полная в руководстве Objective-C.

когда я был доказательством чтения моего поста, мне пришла в голову мысль, и я ответил на свой собственный вопрос. Это решение было достаточно неясным, что я решил пойти дальше, создать сообщение и ответить на него сам (так что любые другие новички, как и я, не повесят трубку).

моя ошибка была в...

@property (copy) NSMutableArray *array;

так и должно было быть...

@property (retain) NSMutableArray *array;

ошибка произошла не в том, как я выполнял свой код, а скорее в том, как anObject пытался" скопировать NSMutableArray массив.

как мы все знаем...

mutableArray = [mutableArray copy];

не всегда (или когда-либо, по моему опыту) равно...

mutableArray = [mutableArray mutableCopy];

и это было источником моей проблемы. Просто переключив свойство @с (copy) на (retain), я решил свою проблему.

Я хотел бы приподнять шляпу перед Георгом Фриче. Мне действительно нужно было использовать (копировать) вместо (сохранять), и я бы не знал, что делать без его ввода.

//@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 на месте, чтобы получить желаемые результаты.

Ура Георг! Z@K!

Я получал ту же ошибку, хотя мои свойства были сильными (используя ARC), и я выделил массив с помощью NSMutableArray.

то, что происходило, состояло в том, что я архивировал изменяемый массив (поскольку он содержит пользовательские объекты) для будущего использования и при декодировании он возвращает неизменяемую копию.

надеюсь, что это поможет кому-нибудь там.

есть некоторые индексы (в массив данных в другом месте) и хотела иметь их в числовом порядке (по уважительной причине). Сбой до добавления 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, Зак!

меня укусило это исключение для опечатки, которую я сделал, может быть, это сэкономит кому-то 5 минут. о своем времени:

я писал:

NSMutableArray *names = [NSArray array];

вместо:

NSMutableArray *names = [NSMutableArray array];

компилятор не имеет никаких проблем с этим, потому что NSMutableArray также является NSArray, но он аварийно завершает работу при попытке добавить объект.

ошибка возникла в результате попытки добавить объект к типу NSMutableArray, который фактически указывал на объект NSArray. Этот тип сценария показан в некоторых демо-код ниже:

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

Это исключение может произойти, если один из объектов в массиве имеет значение null.