Чтение онлайн

на главную - закладки

Жанры

iOS. Приемы программирования

Нахавандипур Вандад

Шрифт:

person.age = @(counter);

}

NSError *error = nil;

if ([self.managedObjectContext save:&error]){

NSLog(@"Managed to populate the database.");

} else {

NSLog(@"Failed to populate the database. Error = %@", error);

}

}

Обратите внимание: я использую класс NSStringFromClass для преобразования имени класса Person в строку и для последующего инстанцирования объектов такого типа. Некоторые программисты предпочитают типизировать Person как строковый литерал. Но если жестко запрограммировать вашу строку таким образом, может возникнуть проблема. Допустим, позже вы решите изменить имя Person в стеке Core Data, а жестко закодированная строка никуда не денется. Она может привести к аварийному завершению вашего приложения во время исполнения, так как объекта модели с именем Person больше не существует. Но если вы примените вышеупомянутую функцию для преобразования имени класса в обычную строку, то при изменении имени класса или отсутствии такого класса получите ошибку времени компиляции. Такие ошибки выявляются еще до ввода приложения в работу, и у вас будет время их исправить.

Прежде чем продолжать обсуждение, оговорюсь: предполагается, что вы уже заполнили базу данных с помощью последнего написанного нами метода. Далее в общих чертах изложено, как мы собираемся выполнять выборку в фоновом контексте.

1. Создаем фоновый контекст с помощью метода-инициализатора initWithConcurrencyType:, относящегося к классу NSManagedObjectContext, затем передаем этому методу значение NSPrivateQueueConcurrencyType. В результате получаем контекст, имеющий собственную закрытую очередь диспетчеризации. Поэтому, если вызвать в контексте блок performBlock:, этот блок будет выполнен в закрытой фоновой очереди.

2. Затем мы собираемся задать в фоновом контексте значение свойства persistentStoreCoordinator, которое будет равно экземпляру координатора нашего постоянного хранилища данных. Таким образом мы свяжем фоновый контекст с координатором постоянного хранилища. В результате, если выполнить выборку в фоновом контексте, эта операция позволит получить данные прямо с диска или из любого другого места, где их может хранить координатор.

3. Выполняем в фоновом контексте вызов performBlock:, а затем даем запрос на выборку. В рамках этого запроса требуется найти в стеке Core Data всех людей, чей возраст относится к диапазону от 100 до 200. Подчеркиваю: реалистичность эксперимента нас в данном случае не волнует. Я хочу лишь продемонстрировать, как действует выборка данных в фоновом режиме. Создавая запрос выборки данных, мы устанавливаем его свойство resultType в значение NSManagedObjectIDResultType. Так мы гарантируем, что результаты, возвращаемые после выполнения этого запроса на выборку, состоят не из управляемых объектов как таковых, а только из ID этих объектов. Как объяснялось ранее, мы не собираемся выбирать сами управляемые объекты, поскольку при выборке этих объектов в фоновом контексте не сможем использовать их в основном потоке. Итак, в фоновом контексте мы только выбираем их ID, а преобразуем эти ID в реальные управляемые объекты уже в главном контексте. После этого такие объекты можно использовать в основном потоке.

Вот как создается запрос на выборку:

— (NSFetchRequest *) newFetchRequest{

NSFetchRequest *request = [[NSFetchRequest alloc]

initWithEntityName:

NSStringFromClass([Person class])];

request.fetchBatchSize = 20;

request.predicate =

[NSPredicate predicateWithFormat:@"(age >= 100) AND (age <= 200)"];

request.resultType = NSManagedObjectIDResultType;

return request;

}

А вот как мы будем создавать фоновый контекст и выполнять в нем запрос на выборку данных:

— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

__weak NSManagedObjectContext *mainContext = self.managedObjectContext;

__weak AppDelegate *weakSelf = self;

__block NSMutableArray *mutablePersons = nil;

/* Создаем фоновый контекст */

NSManagedObjectContext *backgroundContext =

[[NSManagedObjectContext alloc]

initWithConcurrencyType: NSPrivateQueueConcurrencyType];

backgroundContext.persistentStoreCoordinator =

self.persistentStoreCoordinator;

/* Выполняем блок в фоновом контексте */

[backgroundContext performBlock: ^{

NSError *error = nil;

NSArray *personIds = [backgroundContext

executeFetchRequest: [weakSelf newFetchRequest]

error:&error];

if (personIds!= nil && error == nil){

mutablePersons = [[NSMutableArray alloc]

initWithCapacity: personIds.count];

/* Теперь переходим в главный контекст и получаем эти объекты

в главном контексте, исходя из их ID */

dispatch_async(dispatch_get_main_queue, ^{

for (NSManagedObjectID *personId in personIds){

Person *person = (Person *)[mainContext

objectWithID: personId];

[mutablePersons addObject: person];

}

[weakSelf processPersons: mutablePersons];

});

} else {

NSLog(@"Failed to execute the fetch request.");

}

}];

self.window = [[UIWindow alloc]

initWithFrame: [[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

Этот код собирает все управляемые объекты в виде массива, а затем вызывает в делегате нашего приложения метод processPersons:, обрабатывающий результаты массива. Напишем этот метод следующим образом:

— (void) processPersons:(NSArray *)paramPersons{

for (Person *person in paramPersons){

NSLog(@"First name = %@, last name = %@, age = %ld",

person.firstName,

person.lastName,

(long)person.age.integerValue);

}

}

См. также

Разделы 7.4, 16.4 и 16.6.

16.10. Использование специальных типов данных в модели Core Data

Поделиться:
Популярные книги

Как я строил магическую империю 3

Зубов Константин
3. Как я строил магическую империю
Фантастика:
попаданцы
постапокалипсис
аниме
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 3

Геном хищника. Книга седьмая

Гарцевич Евгений Александрович
7. Я - Легенда!
Фантастика:
боевая фантастика
рпг
фэнтези
попаданцы
5.00
рейтинг книги
Геном хищника. Книга седьмая

Отряд

Валериев Игорь
5. Ермак
Фантастика:
альтернативная история
5.25
рейтинг книги
Отряд

Твое сердце будет разбито. Книга 1

Джейн Анна
Любовные романы:
современные любовные романы
5.50
рейтинг книги
Твое сердце будет разбито. Книга 1

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Сталин

Радзинский Эдвард Станиславович
3. Загадки жизни и смерти
Проза:
историческая проза
7.36
рейтинг книги
Сталин

Наномашины, сынок! Том 1

Новиков Николай Васильевич
1. Чего смотришь? Иди книгу читай
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наномашины, сынок! Том 1

Газлайтер. Том 15

Володин Григорий Григорьевич
15. История Телепата
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Газлайтер. Том 15

Охотник за головами

Вайс Александр
1. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Охотник за головами

Отверженный. Дилогия

Опсокополос Алексис
Отверженный
Фантастика:
фэнтези
7.51
рейтинг книги
Отверженный. Дилогия

Приключения русского дебютанта

Штейнгарт Гари
Проза:
современная проза
5.00
рейтинг книги
Приключения русского дебютанта

Имперец. Том 3

Романов Михаил Яковлевич
2. Имперец
Фантастика:
боевая фантастика
попаданцы
альтернативная история
7.43
рейтинг книги
Имперец. Том 3

День поминовения

Нотебоом Сэйс
Проза:
современная проза
5.00
рейтинг книги
День поминовения