iPhone Tableview не работает для тестировщиков Apple

Моя заявка была отклонена, так как приложение не работало во время проверки группой проверки приложений для iPhone. Предполагается, что приложение загружает слова в табличное представление, но не делало этого во время обзора. Тем не менее, приложение отлично работает на моем iPhone. Не могли бы вы дать мне какие-либо предложения относительно того, почему приложение будет работать идеально на одном iPhone, но не на iPhone, используемом в процессе проверки?

Вот технические детали:

  1. Проект был скомпилирован на MacBook Pro под управлением Mac OS X 10.6.2 (10C540).
  2. Версия Xcode 3.2.1 64-разрядная среда разработки Xcode: 1613.0 Ядро Xcode: 1614.0 Поддержка инструментов: 1591.0
  3. Базовая версия SDK 3.1.3
  4. Уровень оптимизации: самый быстрый, самый маленький [-Os]
  5. Мой iPhone 3GS с ОС 3.1.3

Подозреваю, что метод -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath не вызывается. Этот метод находится в делегате, определенном как @interface WordTableViewController : GenericTableViewController , где класс GenericTableViewController определен как @interface GenericTableViewController : UITableViewController .

Я подозреваю, что это так, потому что в какой-то момент моей разработки отладка версии выпуска на iPhone показала, что -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath не вызывался, хотя он вызывался при отладке отладочной версии на том же iPhone. Я решил эту проблему после нескольких дней расследования. Я решил это, просто изменив уровень оптимизации в конфигурации выпуска, а затем вернув его к исходному значению. Это было очень странно для меня.

Для самой последней рассматриваемой отправки приложения я воссоздал конфигурацию распространения, продублировав конфигурацию функционирующего выпуска. Затем я создал специальную конфигурацию, продублировав эту конфигурацию дистрибутива. Теперь приложение отлично работает на моем iPhone для выпуска, отладки и специального распространения. Однако в Apple он не работает.

Ваши комментарии будут ОЧЕНЬ высоко оценены!


person user273565    schedule 26.02.2010    source источник


Ответы (2)


Одна вещь, чтобы рассмотреть. NSUserDefaults.

Когда вы выполняете свои тестовые случаи, у вас есть тестовые примеры, где UserDefaults:

  1. Пустой.
  2. Поврежден.

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

Если вы не используете NSUserDefaults для хранения данных о состоянии, нам потребуется дополнительная информация.

person Steven Noyes    schedule 26.02.2010
comment
Спасибо, Стивен. Я не использую NSUserDefaults. Однако мне интересно, имеет ли смысл мой последний комментарий к ответу Брэда. Я считаю, что мне могло сойти с рук то, что мне не должны были позволять делать. А именно, освобождение NSMutableArray, а затем его повторное заполнение при каждом поиске. Я добавлю код в свой следующий комментарий. (Мне почти не хватило места в этом блоке текста.) - person user273565; 26.02.2010
comment
// Используется для выпуска здесь: [list removeAllObjects]; while(sqlite3_step(statement) == SQLITE_ROW && (limit == NO || [счетчик списка] ‹= INITSEARCHROWS)) { NSMutableArray *columns = [[NSMutableArray alloc] init]; for(int i = 0; i ‹ 7; i++) { NSString *value; char *column = (char *) sqlite3_column_text (оператор, я); if (column == nil) { value = [[NSString alloc] initWithUTF8String:]; } else { value = [[NSString alloc] initWithUTF8String:column]; } [столбцы addObject:значение]; [выпуск стоимости]; } [список addObject:столбцы]; [выпуск колонок]; } [sql closeDatabase]; [распределение SQL]; } - person user273565; 26.02.2010
comment
В ПОРЯДКЕ. Большая часть этого выглядит нормально. У меня есть вопрос о том, кому принадлежит память из sqlite3_column_text(statement, i); вызов. Точно так же [[NSMutableArray alloc] init] действительно должен быть [[NSMutableArray alloc] initWithCapacity:8]. NSMutableArray НЕ переопределял init, есть вероятность, что какой-то код не вызывается, что действительно должно быть. Также используйте удобные методы arrayWithCapacity:, stringWithUTF8String:. Они удалят множество релизов из вашего кода и сделают вашу жизнь проще. - person Steven Noyes; 26.02.2010
comment
Еще раз спасибо. Я внес изменения в initWithCapacity:8. Кроме того, в документе SQLite указано, что пространство памяти, используемое для хранения строк и больших двоичных объектов, освобождается автоматически. Не передавайте указатели, возвращенные sqlite3_column_blob(), sqlite3_column_text() и т. д., в sqlite3_free(). Так что все в порядке. Хороший момент с arrayWithCapacity, поскольку он в основном эквивалентен [[[NSMutableArray alloc] initWithCapacity: 1] autorelease], это более удобно. stringWithUTF8String аналогичен. Я буду использовать их часто! - person user273565; 27.02.2010

Помимо начала очистки, как предлагает Стивен (полностью удалите приложение с вашего iPhone и переустановите его), основные причины непоследовательного поведения между устройствами, по-видимому, связаны с памятью и потоками.

Вы заявляете, что используете iPhone 3G S, в котором значительно больше памяти, чем в старых моделях iPhone/iPod touch. Если вы можете, протестируйте свое приложение на одном из этих старых устройств самостоятельно или найдите кого-нибудь, готового провести бета-тестирование вашего приложения (вы упомянули, что у вас есть работающая специальная сборка, так что вы в основном готовы к этому). Если вы не можете получить доступ к одному из этих устройств, запустите свое приложение на своем устройстве с помощью инструмента Memory Monitor (не ObjectAlloc) и наблюдайте за пиковым использованием памяти вашим приложением. Если в какой-либо момент он превысит 20 МБ, возможно, на старых устройствах будут отправлены предупреждения о нехватке памяти, которые ваше приложение может обрабатывать неправильно. Вы можете искусственно вызывать предупреждения о нехватке памяти в Симуляторе, используя Hardware | Смоделируйте предупреждение о памяти и посмотрите, что произойдет.

Если вы используете какие-либо фоновые потоки для обработки, они также могут привести к недетерминированному поведению. В iPhone 3G S процессор намного быстрее, чем в ранних моделях iPhone/iPod touch, поэтому на вашем устройстве процессы могут выполняться в другом порядке, чем на их. Убедитесь, что вы правильно блокируете доступ к общим ресурсам и не выполняете обновления пользовательского интерфейса в фоновом потоке.

person Brad Larson    schedule 26.02.2010
comment
Большое тебе спасибо! 1) Я удалил старое приложение со своего iPhone. 2) Мне не удалось одолжить 3G. Я также не смог найти инструмент под названием «Менеджер памяти». Вы подчеркнули, что имели в виду нечто иное, чем выделение объектов, поэтому я предположил, что вы имели в виду утечки. (надеюсь я вас правильно понял). Поэтому я использовал Instruments в своей сборке Release, пока она работала на моем iPhone. Утечек нет. При запуске приложение использует 610 КБ. Функциональность, которая не работает в Apple, использует 1,92 МБ. Наиболее интенсивная функция использует 6,20 МБ. В фоновом потоке нет явных обновлений пользовательского интерфейса. - person user273565; 26.02.2010
comment
Тот факт, что настройка оптимизации вообще имела какой-либо эффект, говорит мне о том, что вы правы в том, что вещи могут выполняться в другом порядке. Сейчас я смотрю на свой код таблицы. Я подозреваю, что источник данных (изменяемый массив, который является членом базового класса моего табличного представления) может быть связан с проблемой. Когда пользователь выполняет поиск в моем приложении, он заполняет таблицу результатами. Раньше я освобождал изменяемый массив, а затем перераспределял и снова заполнял его при каждом поиске. Я просто изменил это и выделил один раз при загрузке представления, а затем сделал removeAllObjects и повторно заполнил массив при каждом поиске. - person user273565; 26.02.2010
comment
Я имею в виду прибор Memory Monitor. В разделе «Инструменты» перейдите в библиотеку и перетащите инструмент «Монитор памяти» в список инструментов и перезапустите приложение (или выберите его запуск из раскрывающегося списка «Цель по умолчанию»). Показания, которые он дает, - это истинное использование памяти вашим приложением (ObjectAlloc и другие скрывают большую часть использования памяти вашего пользовательского интерфейса). - person Brad Larson; 26.02.2010
comment
Простое освобождение NSMutableArray и его немедленное воссоздание не должно вызывать проблем, если это делается в основном потоке, потому что это должно блокировать любые обновления пользовательского интерфейса до завершения всей операции. Тем не менее, я видел проблемы с порядком выполнения раньше с UITableView на 3.0 (у Apple есть обходные пути, перечисленные в справочнике по классу UITableView для одной такой проблемы). - person Brad Larson; 26.02.2010
comment
Большая помощь! Я буду часто использовать этот инструмент памяти. Выяснилось, что пиковое использование памяти во время рассматриваемой функциональности достигло примерно 12 МБ. В гораздо большей памяти и ресурсоемкой функции приложения (не являющейся частью этой проблемы) пиковая реальная память достигла 32 МБ (виртуальная примерно 300 МБ). MobileSafari и MobileMail также достигают пиковых значений. Утечек не увидел. Все это говорит о том, что я не думаю, что совершаю какие-либо грубые грехи памяти (пожалуйста, поправьте меня, если я ошибаюсь). Тем не менее, я рассмотрю UITable по проблеме 3.0, о которой вы упомянули. Путешествие продолжается. - person user273565; 27.02.2010
comment
На оригинальной модели iPhone вы начинаете получать предупреждения о памяти примерно при 20 МБ, а ваше приложение жестко убивается при 30 МБ, поэтому я бы не стал игнорировать эту часть вашего приложения, даже если это не проблема. - person Brad Larson; 27.02.2010
comment
Спасибо, Брэд. Я потрачу время на оптимизацию перед повторной отправкой на рассмотрение. Означает ли это, что MobileSafari и MobileMail также не работают на оригинальной модели iPhone? Поскольку это всего лишь версия 1.0 приложения, на основе которой будут построены будущие версии, я хочу, чтобы мое приложение с самого начала было как можно более компактным и пуленепробиваемым. (Кстати, это может быть не тот форум, где можно задать этот вопрос, но каковы профессиональные возможности для разработчиков iPhone или разработчиков Mac, помимо маркетинга собственного программного обеспечения? Не стесняйтесь игнорировать вопрос, если он здесь неуместен. .) - person user273565; 27.02.2010
comment
Встроенные приложения имеют возможности, выходящие за рамки тех, которые мы можем написать, поэтому у них нет таких же ограничений. В любом случае, на 3G S они могут просто максимально использовать доступную им дополнительную память. Для обсуждения деловых возможностей iPhone и связанных с этим вопросов я направляю вас в список рассылки iPhoneSB: groups.google. ком/группа/iphonesb - person Brad Larson; 27.02.2010
comment
Спасибо, Брэд. Я проверю сайт. Я действительно беспокоюсь об использовании моей памяти сейчас! Это настоящая проблема для меня. Прежде всего, либо библиотеки iPhone негерметичны, либо я что-то неправильно понимаю. Мое событие textDidChange выглядит как @try { return; ... (Я добавил возврат, чтобы шаг за шагом увидеть, где я начинаю потреблять память.) То же самое с searchButtonClicked. Табличное представление с поисковым представлением при запуске приложения. Я использую 5,04 МБ. Как только я ввожу буквы в строку поиска (или обратно), реальная память становится 8 МБ+ и никогда не освобождается! Почему? Я еще даже не в своем коде. - person user273565; 28.02.2010