Как создать глобальный экземпляр UIManagedDocument для каждого документа на диске, общий для всего моего приложения, используя блоки?
Я пытаюсь создать вспомогательный метод, который будет извлекать UIManagedDocument, а затем открыть и вернуть его, чтобы я мог получить доступ к тому же UIManagedDocument из нескольких мест в моем приложении.
У меня возникают проблемы с асинхронным характером этого, поскольку я не слишком разбираюсь в блоках. В идеале последовательность событий будет следующей:
- Класс X вызывает вспомогательный метод для получения UIManagedDocument и включает блок кода для запуска при возврате открытого документа.
- Метод класса извлекает UIManagedDocument и вызывает по требованию openWithCompletionHandler или saveToURL и включает блок кода для запуска при возврате открытого документа.
- openwithCompletionHandler или saveToURL выполнит свою задачу и с успехом вернется = ДА и запустит код в своем блоке
- Метод класса завершает свою задачу и возвращает с открытым UIManagedDocument и запускает код в своем блоке
Можно ли каким-то образом передать исходный блок?
Вот мой код до сих пор. Любые мысли были чрезвычайно оценены, спасибо.
// This is a dictionary where the keys are "Vacations" and the objects are URLs to UIManagedDocuments
static NSMutableDictionary *managedDocumentDictionary = nil;
// This typedef has been defined in .h file:
// typedef void (^completion_block_t)(UIManagedDocument *vacation);
// The idea is that this class method will run the block when its UIManagedObject has opened
@implementation MyVacationsHelper
+ (void)openVacation:(NSString *)vacationName usingBlock:(completion_block_t)completionBlock
{
// Try to retrieve the relevant UIManagedDocument from managedDocumentDictionary
UIManagedDocument *doc = [managedDocumentDictionary objectForKey:vacationName];
// Get URL for this vacation -> "<Documents Directory>/<vacationName>"
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:vacationName];
// If UIManagedObject was not retrieved, create it
if (!doc) {
// Create UIManagedDocument with this URL
doc = [[UIManagedDocument alloc] initWithFileURL:url];
// Add to managedDocumentDictionary
[managedDocumentDictionary setObject:doc forKey:vacationName];
}
// If document exists on disk...
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path]])
{
[doc openWithCompletionHandler:^(BOOL success)
{
// Can I call the completionBlock from above in here?
// How do I pass back the opened UIDocument
}];
} else {
[doc saveToURL:url
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
// As per comments above
}];
}
}
Ответы
Ответ 1
Вы можете выполнить блок с помощью completeBlock (doc).
[doc openWithCompletionHandler:^(BOOL success)
{
// Can I call the completionBlock from above in here?
// How do I pass back the opened UIDocument
completionBlock(doc);
}];
Предположим, что у вас есть следующий метод, реализованный в классе, который будет вызывать ваш метод openVacation:
-(void)vacationOpened:(UIManagedDocument *)vacation
{
NSLog(@"My Vacation: %@", vacation.description);
}
Пример строки кода, который будет вызывать ваш метод openVacation, будет:
[MyVacationsHelper openVacation:@"MyVacation1" usingBlock:^(UIManagedDocument *vacation){
[self vacationOpened:vacation];
}];
Отпуск (UIManagedDocument *) после каретки означает, что при выполнении блока с использованием скобок - как в completeBlock (doc) -, вам нужно указать (UIManagedDocument *) как параметр. Значение этого параметра будет обозначаться как отпуск внутри указанного блока. То, что я сделал в примере с моим блочным кодом, было вызовом метода в моем текущем классе (self) и передать параметр вместе с этим методом, чтобы я мог использовать его по мере необходимости (я просто сделал NSLog здесь, чтобы убедиться, что он сработал).
Ответ 2
Я нашел довольно полезную статью - Основные данные с единым общим UIManagedDocument"