Прежде всего, избегайте хранения больших двоичных объектов в Базовых данных, сохраняя миниатюры в порядке (хотя вы должны оптимизировать свою модель для этого), но вы должны сохранить полное изображение после его восстановления в папке «Документы».1002 * Вы обязательно должны использовать очередь, либо NSOperationQueue, либо сетевую очередь ASI.Я делаю нечто подобное в моем приложении, которое имеет несколько зависимостей.Таким образом, для каждого из 30 объектов вам нужно, чтобы блок (или рабочая функция) вызывался после загрузки 15 изображений.В идеале вы хотите сделать эту работу вне основного потока.Соберите все эти требования вместе, и я бы сказал, что вам нужно как минимум две очереди, одна для сетевых запросов и одна для рабочих блоков, и вы должны использовать NSBlockOperations, что делает все это намного проще.Итак, код будет выглядеть примерно так ...
// Loop through the objects
for (NSArray *objectParts in objectsToDownload) {
// Create our Object
Object *obj = [Object insertIntoManagedObjectContext:self.moc];
// This is the block which will do the post processing for the object
NSBlockOperation *processBlock = [NSBlockOperation blockOperationWithBlock:^{
// Do post processing here, be very careful with multi-threading CoreData
// it's likely you'll need some class to dispatch you MOCs which have all
// all the observers set up.
// We're gonna assume that all the sub-images have been stored in a instance
// variable:
[obj performPostProcessing];
}];
// Given the list of 15 images which form each object
for (NSURL *part in objectParts) {
// Create the ASI request for this part
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:part];
// Configure the request
[request setDelegate:self];
[request setDidFailSelector:@selector(partRequestDidFail:)];
[request setDidFinishSelector:@selector(partRequestDidFinish:)];
// Store the object in the UserInfo dictionary
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:obj, @"Object", nil];
[request setUserInfo:userInfo];
// Add it as a dependency
[processBlock addDependency:request];
// Add it to our network queue
[networkQueue addOperation:request];
}
// Add the processBlock to our worker queue
[workerQueue addOperation:processBlock];
}
Тогда вам также необходимо написать методы делегата, а didFinish будет выглядеть примерно так ...
- (void)partRequestDidFinish:(ASIHTTPRequest *)request {
// Remember this is one the main thread, so any heavy lifting should be
// put inside a block operation, and queued, which will complicate the
// dependencies somewhat, but is possible.
// Get the result data
NSData *data = [request responseData];
// Get the object that it belongs to from the user info dic
Object *obj = [[request userInfo] objectForKey:@"Object"];
// Keep track of the partial data in the object
[obj storePartialDataForPostProcessing:data];
}
И все это попадет в ваш класс, который подключается к вашему серверу и создает ваши объекты, так что это не контроллер представления или что-то еще, а обычный подкласс NSObject.У него должно быть две очереди, контекст управляемого объекта (и, скорее всего, метод, который возвращает другой MOC для использования в потоках, что-то вроде этого:
// Fends a MOC suitable for use in the NSBlockOperations
- (NSManagedObjectContext *)moc {
// Get a blank managed object context
NSManagedObjectContext *aContext = [[UIApplication sharedApplication] managedObjectContext;
[aContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(mergeChangesFromMOC:) name:NSManagedObjectContextDidSaveNotification object:aContext];
return aContext;
}
- (void)mergeChangesFromMOC:(NSNotification *)aNotification {
@try {
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:aNotification];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:[aNotification object]];
}
@catch (NSException * e) {
NSLog(@"Stopping on exception: %@", [e description]);
}
@finally {}
}
Вам также нужно будет каким-то образом отслеживать ход выполнения, ставить в очередь неудачные загрузки, отменять и сохранять MOC в конце. Повторное постановка неудачных загрузок довольно сложно. В любом случае, надеюсь, это поможет.
Итак, просто чтобы уточнить, что в вашем методе делегата вы сохранили загруженный образ во временной переменной экземпляра вашего объекта. Затем, когда все 15 зависимостей закончатся, вы сможете получить доступ к этой переменной экземпляра и выполнять свою работу.1017 *