#ios #delegates #model #nsnotification
#iOS #делегаты #Модель #nsnotification
Вопрос:
В настоящее время я думаю о модели данных для моего приложения iOS. Приложение получает информацию только с сервера, и, следовательно, сама «модель» обычно выполняет все веб-запросы, …
Однако эти сетевые запросы должны выполняться в фоновом режиме — я имею в виду другую задачу, а не фоновое состояние iOS — и после завершения запроса информация в приложении должна быть обновлена.
Было бы разумнее написать делегат для информирования контроллера или я мог бы также использовать NSNotificationCenter? Я думаю, что решение на основе NSNotification могло бы сделать модель более универсальной, например, в настольном приложении.
И, возможно, я должен добавить: модель (поскольку она сохраняет некоторую информацию о сеансе) является одноэлементной, поэтому обычный метод на основе делегирования не будет работать…
Ответ №1:
Я не думаю, что было бы хорошей идеей использовать отдельный поток для обработки обмена данными. Помимо того, что оно сложное, в нем нет необходимости, поскольку NSURLConnection/NSURLRequest
оно позволяет обрабатывать обмен данными асинхронно, то есть без блокировки.
Подробнее, вы можете создать NSURLRequest, выполняющий:
NSURLRequest* yourReq = [NSURLRequest requestWithURL:yourURL];
затем создайте NSURLConnection с:
NSURLConnection* yourConnection = [NSURLConnection connectionWithRequest:yourReq delegate:yourDelegate];
и запустите его с:
[yourConnection start];
Когда данные будут готовы, будет вызван один из методов для вашего делегата ( connectionDidFinishLoading:
, или connection:didFailWithError:
), чтобы вы могли обновить свой пользовательский интерфейс.
Все это без блокировки.
Еще лучшей альтернативой использованию NSURLConnection/NSURLRequest
является использование ASIHTTPRequest, который, по-видимому, более гибок в управлении памятью, а также предлагает отличный механизм кэширования.
РЕДАКТИРОВАТЬ: если вас беспокоит то, что, поскольку ваша модель является одноэлементной, у вас не может быть делегата, позвольте мне предложить вам подробнее изучить этот вопрос.
Ваша модель может быть одноэлементной, и делегат вашего запроса может не иметь никакого отношения к модели, кроме знания того, как получить к ней доступ (что довольно тривиально, поскольку модель является одноэлементной).
Это возможно с помощью нескольких механизмов с NSURLConnection
, но если вы используете ASIHTTPRequest
, это станет действительно легко, потому что у каждого ASIHTTRequest
может быть свой собственный делегат.
Комментарии:
1. Спасибо, на данный момент я действительно использую NSURLConnection вот так: D эта вещь ASIHTTPRequest выглядит действительно потрясающе, поскольку я также загружаю большие файлы в свое приложение…
2. Вы всегда должны обрабатывать обмен данными в отдельном потоке, иначе пользовательский интерфейс зависнет на время обмена данными. Вопрос только в том, создаете ли вы поток самостоятельно или позволяете API делать это за вас.
3. @chrischw_de Я тоже могу порекомендовать ASIHTTPRequest.
4. @Erik B: асинхронный ввод-вывод обрабатывается операционной системой с помощью прерываний. Это устраняет необходимость использования потоков, чтобы избежать блокировки. Прерываниям присуще неблокирующее поведение. Здесь у вас есть более подробная информация: en.wikipedia.org/wiki/Asynchronous_I/O#Signals_.28interrupts.29
5. @chrischw_de: если вы считаете, что не можете использовать делегат, потому что ваша модель является одноэлементной, посмотрите Мою правку.
Ответ №2:
Решение делегирования действительно работает и рекомендуется. Это выглядит примерно так:
[[DataLayer sharedInstance] fetchDataWithDelegate:self];
Этот метод может создавать фоновый поток и отвечать делегату в основном потоке.
Комментарии:
1. Хорошо, спасибо. Но в целом, нет ничего плохого в том, чтобы сделать такую модель одноэлементной, верно?
2. Почти в каждом приложении, с которым я работал, мы использовали одноэлементный класс в качестве точки входа на уровень данных. Я не думаю, что в этом есть что-то неправильное. Я знаю, что некоторые люди считают singleton плохой вещью в целом, но я не вижу в этом проблемы.