Блог О пользователеiphonesdk

Регистрация

 
     
ЯнварьФевральМартАпрельМайИюньИюльАвгустСентябрьОктябрьНоябрьДекабрь
            

 

Как отключать все вызовы NSLog для release-сборки


Опыт показывает, что перед release-сборкой очередной версии (для отправки в AppStore) комментировать десятки или даже сотни отладочных выводов в консоль слишком утомительно, да и не всегда полезно (некоторые выводы в консоль могут ещё пригодиться). Добавьте удобную макрофункцию где-нибудь в общий заголовок проекта (который включаете почти везде, например пусть это будет AppMacros.h).

#ifdef DEBUG
#define DLog(f, ...) NSLog(f, ## __VA_ARGS__)
#else
#define DLog(f, ...)
#endif

Теперь с помощью Find and Replace замените все NSLog на DLog. Если в некоторых исходниках вылезут ошибки компиляции, то добавьте в эти исходники #include "AppMacros.h"

 
 
 

Отладка приложений работающих с серверами


Очень важно тестировать приложения на настоящих iPhone-девайсах, чтобы была возможность вместо конторского Wi-Fi быстрого соединения включить медленный интернет (отключив 3G). Тем самым удаётся приблизить поведение приложения к реальным условиям обычного пользователя.

При этом часто всплывают наружу неудачные решения в области GUI. Например, когда приложение просто замерзает вместо показа хотя бы активити-индикатора на фоне полупрозрачного окна, перегораживающего все контролы. На этом полупрозрачном окне кроме активити-индикатора можно показать надпись "Загрузка данных...". Считаю, что это более юзабильно.

В идеале длительную загрузку или отправку данных лучше делать в отдельном потоке, но при этом разработка приложения усложняется - нужно как-то предусматривать use cases, при которых пользователь захочет совершать действия с данными, которые в этот момент изменяются в другом потоке.

 

О важности IBOutlet прикрепления объектов к объекту-хозяину


Очень важно, если вы решили часть рутинных операций возложить на такой удобный инструмент как Interface Builder не забывать об одном правиле. Каждый объект, который создаётся не динамически в коде (например smthObject = [[SmthClass alloc] initWith... ]), а создан с помощью Interface Builder, каждый такой объект должен иметь своего хозяина (разве что главный делегат приложения гарантированно работает по умолчанию).

То есть любой ваш объект (созданный с помощью Interface Builder) должен принадлежать кому-нибудь как IBOutlet-переменная. Я убеждался в этом уже много раз на практике. Иначе  происходят падения программы при попытке заставить этот объект что-либо сделать, из-за того, что у этого объекта (если он не принадлежит никому как IBOutlet-переменная) например вызывается метод, а объект вроде не существует (раз ни к кому не принадлежит). Может быть гуру-программисты дадут более точное объяснение этому явлению...