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

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

Жанры

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

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

На границе империй. Том 10. Часть 6

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 6

Менталист. Трансформация

Еслер Андрей
4. Выиграть у времени
Фантастика:
фэнтези
альтернативная история
7.28
рейтинг книги
Менталист. Трансформация

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

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

Уникум

Поселягин Владимир Геннадьевич
1. Уникум
Фантастика:
альтернативная история
4.60
рейтинг книги
Уникум

Тьма чернее ночи

Коннелли Майкл
7. Гарри Босх
Детективы:
триллеры
7.64
рейтинг книги
Тьма чернее ночи

Офицер-разведки

Поселягин Владимир Геннадьевич
2. Красноармеец
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Офицер-разведки

Сфирот

Прокофьев Роман Юрьевич
8. Стеллар
Фантастика:
боевая фантастика
рпг
6.92
рейтинг книги
Сфирот

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Товарищ "Чума" 6

lanpirot
6. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Товарищ Чума 6

Сопротивление

Осадчук Алексей Витальевич
11. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
7.33
рейтинг книги
Сопротивление

Последний Паладин. Том 8

Саваровский Роман
8. Путь Паладина
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Последний Паладин. Том 8

Лондон

Резерфорд Эдвард
The Big Book
Проза:
историческая проза
6.67
рейтинг книги
Лондон

Запрети любить

Джейн Анна
1. Навсегда в моем сердце
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Запрети любить

Инженер Петра Великого 3

Гросов Виктор
3. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Инженер Петра Великого 3