Иногда бывает необходимо узнавать о том, когда клавиатура собирается появиться или спрятаться (например, когда текстовые поля находятся в таблице и приходится уменьшать высоту таблицы так, чтобы она вся была над клавиатурой). Для этого есть 4 типа уведомлений с такими именами:
- UIKeyboardWillShowNotification — клавиатура должна появится,
- UIKeyboardDidShowNotification — клавиатура появилась,
- UIKeyboardWillHideNotification — клавиатура должна спрятаться,
- UIKeyboardDidHideNotification — клавиатура наконец спряталась.
Так вот…
Если, например, просто вызвать метод resignFirstResponder у объекта класса UITextField, то все хорошо, и мы получаем оба уведомления — UIKeyboardWillHideNotification и UIKeyboardDidHideNotification. Но, если в момент редактирования какого-то из текстовых полей будет осуществлена установка курсора в другое текстовое поле, то, как выяснилось, уведомление UIKeyboardDidHideNotification не приходит, при том что приходит UIKeyboardWillHideNotification, а затем UIKeyboardWillShowNotification и UIKeyboardDidShowNotification. Возможно, это вызвано тем, что клавиатура не успевает спрятаться до того, как снова начинает появляться :) Но, в любом случае, нужно иметь это ввиду, если вы собираетесь использовать эти уведомления.
Вы думали тут будет моё résumé? Вы ошиблись. Не будет. А будут мысли по-поводу. Дело в том, что я нашел новый подкаст. Новый — потому что старым всегда останется «Java Posse», великолепный подкаст про Java и все около-Jav'ное. И этот новый подкаст — Stack Overflow. В этих подкастах есть неуловимый дух безумия и какой-то предельно приятной гиковости. Авторы рассказывают о разных вещах так, как мне интересно. Они общаются со мной (пускай это и их «монолог») так, как мне это приятно слушать. Здоровый юмор, игра словами и приличное качество самого подкаста (как техническое, так и качество подбора новостей/тем) отлично дополняют картину.
Так о чем это я? А, да, «CV». Уже какой подкаст подряд эта тема всплывает в Stack Overflow, каждый раз с разных сторон. Сначала — как боковая тема, ответвленная от обсуждения сайта авторов подкаста. Потом — как обсуждение необходимости тестера им же в проект, далее — обсуждение вопроса. Джоел (дада, тот самый, www.joelonsoftware.com/) и Джефф (Jeff Artwood) очень подробно объясняют, как они просматривают резюме, на что можно, на что нужно обратить внимание при написании и при анализе резюме. Это безумно интересно.
Главный вывод — нужно сделать резюме оригинальным. Дарю идею — резюме iPhone-разработчика в виде программы для iPhone. Второй вывод — забейте на ваш опыт, напишите то, чем вы отличаетесь от остальных разработчиков, почему выбрать нужно именно вас. А опыт — кому он нужен?
Вывод? Мораль? У меня — скучное и никому не нужное резюме. У вас — тоже, могу поспорить. Буду исправляться. Чего и вам советую :)
Поскольку интересных новостей сегодня нет, придется комментировать неинтересные. Сегодня по многим информационным ресурсам прошел слух, что вместо планшетника Apple 27 января представит новый iMac с сенсорным дисплеем с поддержкой Multi-Touch.
Давайте подумаем, верить этому или нет? С одной стороны — сенсорный экран и Multi-Touch это круто, модно и современно. Но как с ним работать? Большинство владельцев больших мониторов сидит от них на расстоянии значительно превышающем длину руки. Но даже если сесть близко — руку придется вытягивать горизонтально или даже задирать вверх, и она быстро устанет. Чтобы руки не уставали, монитор надо положить горизонтально, а это уже совсем странно будет выглядеть, особенно если в нем 22 дюйма. Да и Mac OS X не совсем подходит для управления руками, не говоря уже о популярных программах для нее. Итак, экран надо уменьшить, систему поставить другую и в итоге… мы получаем планшетник, с которого все и начиналось. Странно, правда?
По умолчанию Xcode не позволяет запускать на отладку приложения с правами root и для основной массы приложений это не создает никаких проблем. Тем не менее, в ряде случаев для работы приложения права root просто необходимы.
Самый простой вариант решения этой проблемы — запуск самого Xcode с правами root.
sudo /Developer/Applications/Xcode.app/Contents/MacOS/Xcode
Хотя на мой взгляд это самый плохой вариант который только можно придумать. Можно пойти по Unix way, запустить под root отладчик gdb и уже в нем отлаживать приложение… Тоже не красивое решение, все же отладка в Xcode куда удобнее.
Итак, запусить приложение на отладку с правами root в Xcode все же можно. Для этого необходимо проделать следующие действия.
Разблокировать пользователя root на локальной машине
1. Запустить Directory Utility (находится в папке /System/Library/CoreServices/Directory Utility.app).
2. Зайти в Edit→Enable Root User и задать пароль для пользователя root.
Разблокировать удаленное соедининиие с компьютером
В System Preferences→Sharing выбирается пункт Remote Loging. Данная опция активирует на компьютере ssh демон.
Создать ключи и скопировать их в нужную папку
1. Открыть терминал и ввести ssh-keygen -t rsa
2. Принять расположение по умолчанию и задать пароль.
3. Зайти под пользователем root и создать папку ~/.ssh (~ == /var/root)
4. Скопировать публичные ключи в папку root:
cat ~/.ssh/id_rsa.pub | ssh root@localhost "cat ->> ~/.ssh/authorized_keys"
5. Проверить что все нормально
ssh root@localhost
Включить удаленную отладку при помощи ssh в Xcode
1. Выбрать Get Info для выполнимого файла.
2. В настройках Debugging выбрать Debug executable remotely via ssh и в поле Connect to указать root@localhost.
Можно приступать к отладке :)
При чтении официальной документации посвященной iPhone OS, складывается впечатление что существуют всего 2 паттерна проектирования: Model View Controller и Delegate. В принципе, я согласен с таким подходом, описывать большое количество паттернов скорее вредно чем полезно, особенно для нового в какой-либо области человека. Тем не менее, я люблю пользоваться удобными и привычными подходами пусть даже и на новой платформе.
Загоревшись идеей заполучить в свое распоряжение паттерн Singleton, я немного погуглил и нашел на сайте stackoverflow.com достаточно интересную дискуссию на тему правильного синглтона для Objective C. С одной стороны, приводимые там реализации достаточно хороши, но не на столько, как хотелось бы. По большому счету, почти все «велосипедные» реализации этого паттерна на C++ имеют ту же проблему — отсутствие возможности провести деинициализацию объекта при завершении приложения. При том что Objective C имеет бесшовную состыковку с C, проблема решается достаточно просто. Можно зарегистрировать обработчик, который будет вызван при завершении работы приложения при помощи функции atexit(). Единственное что стоит не забывать при работе с функцией atexit, так это ограничение на возможное количество обработчиков — 32 штуки. За более детальной информацией можно обратиться в стандарт языка C, пункт 7.20.4.2 В результате должен получиться приблизительно следующий код:
// --- файл singleton.h --
@interface Singleton : NSObject {
}
+(Singleton*) instance;
@end
// -- файл singleton.m --
#import "Singleton.h";
@implementation Singleton
static Singleton *instance_;
static void singleton_remover() {
[instance_ release];
}
+ (Singleton*)instance {
@synchronized(self) {
if( instance_ == nil ) {
[[self alloc] init];
}
}
return instance_;
}
- (id)init {
self = [super init];
instance_ = self;
atexit(singleton_remover);
return self;
}
- (void)dealloc {
[super dealloc];
}
@end
К сожалению, в связи с отсутствием в Objective C такого понятия как шаблоны, код получается не универсальный и требует работы по принципу cut and paste, что не радует. Наверное, можно пойти по пути преобразования типов и изменить возвращаемый в instance тип на id. Но при детальном рассмотрении подобный подход мне нравится еще меньше.