#iphone #xcode #nsmutabledictionary
#iPhone #xcode #nsmutabledictionary
Вопрос:
Я ВНЕС ЕЩЕ ОДНУ ПРАВКУ (для увеличения странности), ОТРЕДАКТИРОВАННУЮ, чтобы показать соответствующую часть кода
Привет. С NSMutableArray возникла странная проблема, которую я просто не понимаю…
Объяснение:
У меня есть NSMutableArray, определенный как свойство (неатомное, сохранять), синтезированный и инициализированный 29 элементами.
realSectionNames = [[NSMutableArray alloc] initWithCapacity:29];
После инициализации я могу вставлять элементы по своему усмотрению, и, похоже, все работает нормально.
Однако, когда я запускаю приложение, если я вставляю новый элемент в массив, я могу распечатать массив в функции, в которую я вставил элемент, и все кажется нормальным.
Однако, когда я выбираю строку в таблице, и мне нужно прочитать этот массив, мое приложение выходит из строя. Фактически, он больше не может даже печатать массив.
Есть ли какой-нибудь «магический и логический трюк», который каждый должен знать при использовании NSMutableArray, который новичок вроде меня может упустить?
Большое спасибо.
Я объявляю свой массив как
realSectionNames = [[NSMutableArray alloc] initWithCapacity:29];
Я вставляю объекты в свой массив с
[realSectionNames addObject:[category categoryFirstLetter]];
хотя я знаю, что также могу вставить его с
[realSectionNames insertObject:[category categoryFirstLetter] atIndex:i];
где «i» — это первая незанятая позиция.
После вставки я перезагружаю данные моего TableView. Печать массива до или после перезагрузки данных показывает, что в нем содержится нужная информация.
После этого выбор строки в таблице приводит к аварийному завершению работы приложения. Это REALSECTIONNAME используется в нескольких функциях UITableViewDelegate, но в данном случае это не имеет значения. Что действительно важно, так это то, что печать массива в начале функции didSelectRowAtIndexPath приводит к сбою всего (и, конечно же, ничего не печатает). Я почти уверен, что это в этой строке, для печати всего, что он строкой раньше, работает (пример):
NSLog(@"Anything");
NSLog(@"%@", realSectionNames);
выдает результат:
2010-03-24 15:16:04.146 myApplicationExperience[3527:207] Что угодно
[Сеанс начался в 2010-03-24 15:16:04 0000.] GNU gdb 6.3.50-20050815 (Apple version gdb-967) (Вт 14 июля 02:11:58 UTC 2009) Авторское право 2004 Free Software Foundation, Inc. GDB — это свободное программное обеспечение, на которое распространяется Общая общественная лицензия GNU, и вы можете изменять его и / или распространять его копии при определенных условиях. Введите «показать копирование», чтобы увидеть условия. На GDB нет абсолютно никакой гарантии. Введите «показать гарантию» для получения подробной информации. Этот GDB был настроен как «i386-apple-darwin».sharedlibrary apply-load-rules все подключает к процессу 3527.
Все еще не понимаю, какую глупость я совершил на этот раз… может быть, еще не поздно продолжить карьеру нейрохирурга?
после ответа я напечатал
NSLog(@"self=%x", self);
NSLog(@"self=%@", self);
NSLog(@"realSectionNames=%x", realSectionNames);
выдает точно такие же результаты в каждой функции (от делегата или нет).
NSLog(@"realSections = %@", realSectionNames);
хорошо печатается в моем viewWillAppear, в didSelectRowAtIndexPath и завершается сбоем в viewForHeaderInSection. Между прочим, нет потоков…
Итак, не зная, что делать, я пробую «вещи»… Я изменил все ссылки REALSECTIONNAME на self.realsectionname
печать в разделе viewForHeaderInSection приводит к следующей проблеме:
2010-03-24 16:01:44.067 myApplication[4104:207] numberOfSectionsInTableView result -> 1
2010-03-24 16:01:44.068 myApplication[4104:207] viewForHeaderAtSection
2010-03-24 16:01:44.068 myApplication[4104:207] self=3d13470
2010-03-24 16:01:44.068 myApplication[4104:207] self=<RootViewController: 0x3d13470>
2010-03-24 16:01:44.069 myApplication[4104:207] self.realSectionNames=3b12830
2010-03-24 16:01:44.070 myApplication[4104:207] realSections = (
<__NSArrayReverseEnumerator: 0x3b50500>
)
2010-03-24 16:01:44.070 myApplication[4104:207] *** -[__NSArrayReverseEnumerator length]: unrecognized selector sent to instance 0x3b50500
2010-03-24 16:01:44.071 myApplication[4104:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayReverseEnumerator length]: unrecognized selector sent to instance 0x3b50500'
2010-03-24 16:01:44.072 myApplication[4104:207] Stack: (
31073371,
2572170505,
31455291,
31024758,
30877378,
276908,
26404,
3227182,
4544033,
4551926,
4550923,
3267462,
3207973,
3249408,
25927,
3222086,
3205252,
459178,
30857920,
30854216,
39163413,
39163610,
2949039
)
Что такое NSArrayReverseEnumerator??? И почему это так грубо по отношению ко мне???
Комментарии:
1. Есть шанс увидеть код, который вылетает? Трудно догадаться, в чем может заключаться проблема…
Ответ №1:
Примечание для всех (и особенно для себя)…
Я тупой, очень тупой мальчик.
Я освобождал элемент, который я вставил в массив.
Извините за вопросы, спасибо за ответы…
Ответ №2:
При сбое приложения консоль Xcode сообщит об ошибке, которая привела к сбою приложения. Вы захотите отредактировать свой вопрос, включив в него это сообщение об ошибке вместе с соответствующим исходным кодом, поскольку это поможет другим ответить на ваш вопрос.
Я подозреваю, что выбранная вами строка таблицы пытается указать на индекс в массиве, который не существует. Если это так, вы пытаетесь сослаться на часть массива, которая не существует. Это приводит к тому, что ваше приложение выдает исключение и завершает работу.
Помните, что NSMutableArray
можно инициализировать до определенной емкости, но до тех пор, пока элементы не будут вставлены, он фактически не содержит никаких объектов. -initWithCapacity:
Метод выделяет только определенный объем памяти, но в нем нет заполнителей или nil
записей для 1
сквозных n
индексов.
Ответ №3:
1) Можем ли мы узнать сообщение об ошибке? а соответствующая часть кода?
2) Вот правильный способ объявить ваш массив :
self.realSectionNames = [[NSMutableArray arrayWithCapacity:29];
Комментарии:
1. Нет ничего плохого в использовании alloc и init для создания NSMutableArray, особенно если вам нужно сохранить его после того, как пул авторелиза будет исчерпан.
2. Так зачем же его синтезировать, если вы не используете сеттер?
Ответ №4:
Я подозреваю, что делегат вашего TableView подключен неправильно или к недопустимому объекту. Работают ли какие-либо другие ваши методы делегирования? Попробуйте поместить их в начало didSelectRowAtIndexPath, чтобы проверить значения указателя:
NSLog(@"self=%x", self);
NSLog(@"self=%@", self);
NSLog(@"realSectionNames=%x", realSectionNames);
Комментарии:
1. NSLog(@»self=%x», self); NSLog(@»self=%@», self); NSLog(@»realSectionNames=%x», realSectionNames); выдает точно такой же результат в любом месте. NSLog(@»realSections = %@», realSectionNames); хорошо печатается в моем viewWillAppear, в didSelectRowAtIndexPath и завершается сбоем в viewForHeaderInSection.