Когда возникает необходимость создать в модели отношение «один ко многим» (такое, как показано на рисунке),

то может показаться, что обратные отношения ставить незачем, как и при отношениях «один к одному» . И действительно, ваше приложение запустится и не будет падать из-за этого, хотя компилятор и выдаст вам Warning’и. Но не все так просто… Статья полностью »
Просто обязан написать об этом:)
Сегодня выплыла проблема случайных крешей приложения, примерно следующего плана
EXC_BAD_ACCESS
objc_msgSend + 24
-[UIWebView webView:resource:didFinishLoadingFromDataSource:] + 80
-[UIWebViewWebViewDelegate webView:resource:didFinishLoadingFromDataSource:] + 36
Проверка на двойное и преждевременное освобождение объектов ничего не дала. То есть с памятью проблем небыло. Проблема была в чем-то другом. Судя по call-Tree, было сделано предположение, что UIWebView, вызывает метод делегата, который уже был удален из памяти. По сути, такого произойти не могло, так как обычно такими делегатами являются UIViewController’ы, которые в методе dealloc вызывают [webView release].
Но! Как оказалось, этого совсем недостаточно. Итак – решение проблемы. В методе dealloc, либо в любом месте, где вы прекращаете использовать объект, у которого вы прописаны делегатом, делайте следующее [webView setDelegate:nil]. В таком случае, даже если объект будет слать какие-то сообщения делегату, то приложение не будет вылетать с ошибкой.
Вывод:Как уже было сказано выше – всегда “обNULLяйте” делегата объекта. Ну, и пример кода соотвественно.
// ViewItemController.h
@interface ViewItemController : UIViewController < UIWebViewDelegate> {
UIWebView *webView;
}
@property(nonatomic, retain) IBOutlet UIVebView * webView;
@end
// ViewItemController.m
-(void)viewDidLoad {
[[self webView] setDelegate:self]
}
//
// На самом деле вполне "понятно", что после [webView release],
// совсем не факт, что webView уничтожится, ведь retainCount
// может быть все еще больше 0. Но для понимания этого
// нужно задуматься, а на это время не всегда хватает ;)
-(void) dealloc {
[webView setDelegate:nil];
[webview release];
[super dealloc];
}
Иногда бывает необходимо узнавать о том, когда клавиатура собирается появиться или спрятаться (например, когда текстовые поля находятся в таблице и приходится уменьшать высоту таблицы так, чтобы она вся была над клавиатурой). Для этого есть 4 типа уведомлений с такими именами:
- UIKeyboardWillShowNotification – клавиатура должна появится,
- UIKeyboardDidShowNotification – клавиатура появилась,
- UIKeyboardWillHideNotification – клавиатура должна спрятаться,
- UIKeyboardDidHideNotification – клавиатура наконец спряталась.
Так вот…
Статья полностью »
Многие, наверное, уже пробовали работать с CoreData и хотя бы краем уха слышали/краем глаза видели что-то о поддержке undo/redo для контекста объектов. Дело в том, что существуют механизмы, позволяющие при изменении объектов, унаследованных от NSManagedObject и находящихся в контексте NSManagedObjectContex, производить перемещение по т.н. контекстному графу при помощи методов undo и redo. Вершины этого графа создаются путем вызова у контекста метода processPendingChanges, после чего последующие изменения объектов в контексте можно откатить до их состояния на момент создания вершины методом undo. Также можно перемещаться между созданными вершинами, вызывая методы undo (к предыдущей вершине) или redo (к следующей вершине). За обработку и управление изменениями отвечает undoManager – объект класса NSUndoManager, который есть у объекта- контекста. Сдесь небольшое уточнение – есть, если только вы программируете под Mac OS. В iPhone SDK undoManager не инициализируется при инициализации контекста!
[context undoManager] == nil;// == YES !!!!!!!!
Часто при разработке приложений возникает необходимость осуществить возможность изменения региональных настроек, языка графического интерфейса приложения в зависимости от системных настроек, другими словами, сделать приложение локализированным. Для этого iPhone SDK предоставляет широкий набор средств. О них и пойдет речь в этой статье.
Локализировать можно любые ресурсы приложения – от *.xib – файлов, до отдельных картинок. Также локализацию можно осуществлять программно и получать вручную ресурсы в зависимости от текущей локали окружения, в котором было запущено приложение. Но обо всем попорядку…
При разработке приложения иногда нужно обратиться к адресной книге и получить из нее e-mail. Не все пользователи знают наизусть все свои контакты. Для выбора нужной нам информации существует визуальный компонент. Его лучше показать как модальный, а ViewController, который будет это делать, должен иметь NavigationController. Дальше в пошаговом режиме будет показано как же вызвать этот компонент и получить только нужные данные.
Шаг 1. Подключение frameworks.
Для работы с адресной книгой нам понадобиться 2 фреймворка – AddressBookUI.framework, AddressBook.framework. Первый для визуального отображения компонент похож на приложения Contacts, только без возможности добавить или редактировать контакты. Второй для доступа и работы с данными, которые возвращает визуальный компонент. Если не добавить эти фреймворки и перейти к следующим шагам – приложение работать не будет.
Шаг 2. Установка делегата
Первым делом нужно сделать импорт нужных нам файлов. А нужны нам следующие:
#import <addressbook /AddressBook.h> #import <addressbookui /AddressBookUI.h>
В UIViewController из которого будет вызываться Адресная книга нужно
Статья полностью »
Недавно встала задача следующего плана – программно выставить у UILabel толщину шрифта в bold. После недолгих поисков, выяснилось, что у UIFont вообще отсутствуют понятия вида bold, italic, и тем более bold-italic , максимум, что можно сделать, так это создать системный шрифт, при помощи одного из методов
// Some convenience methods to create system fonts + (UIFont *)systemFontOfSize:(CGFloat)fontSize; + (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize; + (UIFont *)italicSystemFontOfSize:(CGFloat)fontSize;
После увиденного, на горизонте памяти стали всплывать мысли о том, что на самом-то деле не все шрифты могут быть bold или italic. И сразу же появилась мысль – а какие все-таки шрифты могут быть? И какие вообще шрифты есть на устройствах типа iPod / iPhone?
Статья полностью »
Задача в принципе простая, и, как оказалось, нужная.
- Если вдруг, стало нехватать места на системном диске
- Или нужно удалить старый SDK (например 2.2.1), чтобы поставить новый (3.0.5)
- Или просто надоело программировать под iPhone(в Xcode) до такой степени, что просто нельзя больше терпеть его присутствие на жестком диске
(нужное подчеркнуть).
В этом случае, поможет следующая строка, выполнение которой требует прав администратора :
sudo /Developer/Library/uninstall-devtools --mode=all
После ввода пароля, через некоторое время Вы будете польностью освобождены от необходимости созерцать iPhone Development Tools вместе с SDK.
Загрузить файл с внешнего источника в приложение не составит труда. А вот при загрузке в обратном направлении, многие могут столкнуться с трудностями. Сегодня мы будем загружать файл из ресурсов приложения на apache сервер методом POST.
Предположим что у нас в ресурсах находится изображения, которое необходимо загрузить на сервер.
Серверная часть
Нам понадобится apache сервер. В DocumentRoot создадим 2 файла и одну папку. Файл index.php нужен только для тестирования работы серверной части из браузера. В этот файл пишем HTML код формы для отправки.
<form enctype="multipart/form-data" action="uploader.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="100000" /> Choose a file to upload: <input name="uploadedfile" type="file" /> <br /> <input type="submit" value="Upload File" /> </form>
Второй файл будет отвечать за прием изображения. Записать принятое изображение он должен в папку uploads. Ее нужно создать и правильно задать права на запись. Скрипт, отвечающий за прием файлов uploader.php:
$target_path = "uploads/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
В случае возникновения ошибки, скрипт вернет сообщение “There was an error uploading the file, please try again!”. Работу сервера проверяем при помощи браузера. Вызываем скрипт index.php и в форму добавляем небольшой файл. После того как форма будет отправлена, файл должен быть загружен в папку uploads.
Клиентская часть
Для начала необходимо
Статья полностью »
В случае, когда инициализация приложения в iPhone/iPod занимает много времени, это сильно сказывается на первом впечатлении о приложении в целом. Не буду говорить за всех, но мне, например, не нравится, когда после запуска приложения я полчаса вижу черный экран, перед тем, как приложение запустится. Так что эта статья посвящена такой вещи как Splash Screen, и особенностях его установки. Если в двух словах, то в iPhone/iPod приложении – это просто картинка, которая показывается до того, как ваше приложение загрузится. Причем показывается сразу же, как только вы нажали на кнопку запуска приложения, и до тех пор, пока не вызовется
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Это, конечно, первое место в программе (не считая viewDidLoad)
// где мы можем писать код, но до того, как мы попадем сюда
// может пройти достаточно много (относительно) времени
}
как уже говорилось, в статье об индикаторах загрузки, это самый момент подменить Splash Screen, если приложение требует дополнительной загрузки данных. Однако, я немного отвлекся. Итак, устанавливаем Splash Screen.
Установка Splash Screen
Итак. Нам понадобится “.png” файл определенного размера. Почему определенного размера? Об этом чуть дальше. Итак, размер файла должен составлять 320×480(320х460 см. update) пикселей. Делайте что хотите, но если вы вдруг попытаетесь поставить файл другого размера, то вас просто “не поймут”, и откажутся отображать хоть что-то. Будет обидно. Я столкнулся с такой проблемой, и это стоило мне нескольких минут нервов. Кроме опреденного размера, этот файл должен иметь вполне определенное название, а именно Default.png. Причем именно с большой буквы. Иначе – снова не поймут. Насколько мне удалось проверить, в SDK 3.0 тоже особо ничего не поменялось, так что все будет работать. После того, как у нас есть правильноназванноиразмеренный файл, просто добавляем его в проект.
Однако, иногда этого оказывается недостаточно. Причина мне не совсем ясна, но Xcode после добавления файла иногда не добавляет его в ресурсы, и поэтому его приходится руками перетаскивать в нужный target.
Не буду особо разглагольствовать по поводу того, что, по возможности, время загрузки нужно сократить до минимума. Это и так понятно. В случае начальной загрузки, splash screen позволяет немного “сгладить” время ожидания пользователя при запуске приложения, однако, все же не стоит этим злоупотреблять. Терпение пользователей не вечно ;)
UPDATE : Замечание EisernWolf позволило узнать еще одну особенность. Итак, в документации написано следующее :
[...]Default.png: The 480 x 320 pixel image to display when your application is launched. The system uses this file as a temporary background until your application loads its window and user inter face. [...]
. То есть Размер картинки должен быть не 320х460 а 320х480. Однако, это не совсем так. Был проведен эксперимент, попробованы оба варианта картинок, и вот какой результат (кликните на изображение, чтобы увидеть оригинал):
Можно увидеть следующее: Во-первых, оба варианта работают, более того, в обоих вариантах изображение не пережимается. Во-вторых, 20 пикселей изображения 320х480 “съедаются” за счет statusBar’а.
Что же случится, если statusBar’а не будет? (Как отключить statusBar при запуске приложения и много других вкуностей описаны в документации (таблица 1-3)). Добавляем в <PROJECTNAME>.plist файл свойство UIStatusBarHidden в true. Проверяем еще раз:
И вот, что у нас получилось – в случае 320х480 – самый лучший результат – изображение на весь экран, не пережатое. В случае 320х460 – также изображение не пережатое, однако на экране черная полоска сверху 20 пикселей в высоту (там где раньше был statusBar). С изображением 320х400 – все совсем плохо. Во-первых, оно было пережато до 320х460, плюс, черная полоска вверху экрана.
Исходя из опытов, можно сказать следующее – лучше всего для splash-screen’a использовать изображение размером 320х480 – оно будет работать в обоих вариантах(с и без statusBar’a). Однако, необходимо помнить, что в случае, если все-таки statusBar будет включен, то он закроет 20 пикселей вверху изображения.
Исходники проекта Splash-example.
Спасибо, EisernWolf.






















