2010-07-10 3 views
66

Я попытался инициализировать мой NSMutableArray 100 способов с воскресенья, и НИЧЕГО не работает для меня. Я попытался установить его равным недавно выделенному и инициализированному NSMutableArray, просто выделив, инициализируя переменную сам по себе, каждую комбинацию, о которой я мог думать, и всегда тот же результат.NSMutableArray addObject: - [__ NSArrayI addObject:]: нераспознанный селектор отправлен в экземпляр

Вот код:

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" НЕ ноль во время исполнения ...

Я тестировал 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'

кто-нибудь есть какие-либо идеи, что происходит не так ?

ответ

11

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

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

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

- (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!

+0

Обратите внимание, что объявление свойства не должно совпадать с типом ivar, поэтому вы должны использовать' @property (nonatomic, copy) NSArray * array; 'в вашем случае. Также обратите внимание, что ваше свойство неявно атомарно, но реализация вашего сеттера отсутствует - см. [Atomicity] (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html # // apple_ref/DOC/UID/TP30001163-CH17-SW28). –

+1

Наконец, '-mutableCopy' уже возвращает сохраненный экземпляр, поэтому нет необходимости в' [array сохранить ''- см. [Политика владения объектами] (http://developer.apple.com/mac/library/documentation/Cocoa /Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-SW1). –

+0

Еще раз спасибо, мистер Фрицше. Мне было любопытно, что это удержание сохранилось, но, похоже, оно работает в моей программе. По-видимому, у меня есть ошибка в другом месте. :// Вы - мужчина, спасибо за вклад в эту должность и непреднамеренно, мою программу; Я ценю ваше время! С уважением, Z @ K! – Zak

81

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

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

+0

АБСОЛЮТНО ИСПРАВНО!Я понял это, когда писал свой пост, и я опубликовал свое решение ниже. Я действительно не рассматривал переопределение сеттера, но в моем случае мне действительно не нужна копия, поэтому мое решение получилось для меня. Спасибо за быстрый ответ! - Z @ K! – Zak

+1

Ссылка на руководство Objective-C нарушена. – johnnieb

69

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

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

@property (copy) NSMutableArray *array; 

это должно было быть ...

@property (retain) NSMutableArray *array; 

ошибка не происходит так, как я был исполняющим свой код, а в метод anObject пытался «скопировать» массив NSMutableArray.

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

mutableArray = [mutableArray copy]; 

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

mutableArray = [mutableArray mutableCopy]; 

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

+0

У меня была та же проблема, я решил изменить свою переменную из копии, чтобы сохранить ... @Zak +1 для вашего ответа. – Rupesh

+0

Вы должны отметить это как принятый ответ. – NathanAldenSr

+1

'mutableCopy' только что сохранил мою живую – michaelsnowden

-4

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

+1

Не эта конкретная ошибка, нет. Вы получаете другое исключение, если пытаетесь вставить объект nil. –

+0

Кроме того, массивы могут содержать NSNull просто отлично. – stephencelis

3

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

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

Надеюсь, что это поможет кому угодно.

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!

0

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

я писал:

NSMutableArray *names = [NSArray array]; 

вместо:

NSMutableArray *names = [NSMutableArray array]; 

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

0

Ошибка возникла из-за попытки добавить объект к типу 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

Смежные вопросы