问题描述
我正在尝试设计一个帮助方法来检索UIManagedDocument,然后打开并返回它,这样我就可以从我的应用程序中的几个地方访问相同的UIManagedDocument。
I am trying to design a helper method which will retrieve a UIManagedDocument, then open and return it, so that I may access the same UIManagedDocument from several places in my app.
我遇到了异步的问题,因为我对块不太熟悉。理想情况下,事件的顺序是这样的:
I am having trouble with the asynchronous nature of this as I am not too familiar with blocks. Ideally the sequence of events would be this:
- 类X调用帮助器方法来检索UIManagedDocument并包含一个代码块以便在返回打开的文档。
- 类方法检索UIManagedDocument并根据需要调用openWithCompletionHandler或saveToURL,并包含在返回打开的文档时运行的代码块。
- openwithCompletionHandler或saveToURL完成他们的任务,并返回成功= YES并在其块中运行代码
- 类方法完成其任务并返回打开的UIManagedDocument并在其块中运行代码
- Class X calls the helper method to retrieve the UIManagedDocument and includes a block of code to run when the opened document is returned.
- The class method retrieves the UIManagedDocument and calls openWithCompletionHandler or saveToURL as necessary, and includes a block of code to run when the opened document is returned.
- openwithCompletionHandler or saveToURL complete their task, and return with success = YES and run the code in its block
- The class method completes its task and returns with an open UIManagedDocument and runs the code in its block
我可以通过某种方式传递原始块吗?
Can I pass the original block through somehow?
到目前为止,这是我的代码。任何想法都非常感谢,谢谢。
Here's my code so far. Any thoughts hugely appreciated, thanks.
// 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
}];
}
}
推荐答案
您可以使用completionBlock(doc)执行该块。
You can execute the block with completionBlock(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方法:
Let's assume that you have the following method implemented in the class that will be calling your openVacation method:
-(void)vacationOpened:(UIManagedDocument *)vacation
{
NSLog(@"My Vacation: %@", vacation.description);
}
调用openVacation方法的示例代码行将是:
A sample line of code that would call your openVacation method would be:
[MyVacationsHelper openVacation:@"MyVacation1" usingBlock:^(UIManagedDocument *vacation){
[self vacationOpened:vacation];
}];
插入符后的(UIManagedDocument * vacation)意味着当您使用括号表示法执行块时 - - 与 completionBlock(doc) - 一样,您需要列出(UIManagedDocument *)作为参数。该参数的值将在指定的块内称为 vacation 。我在上面的块代码示例中所做的是在我当前的类中调用一个方法(self)并将参数传递给该方法,以便我可以根据需要使用它(我只是在这里做了一个NSLog以确保它工作) 。
The (UIManagedDocument *vacation) after the caret means that when you execute the block using the parentheses notation -- as in completionBlock(doc) --, you need to list a (UIManagedDocument *) as a parameter. The value of that parameter will be referred to as vacation inside the specified block. What I did in my block code sample above was call a method in my current class (self) and pass the parameter along to that method so that I could use it as needed (I just did an NSLog here to make sure that it worked).
这篇关于如何使用块为我的整个应用程序共享的每个磁盘上的文档创建一个全局UIManagedDocument实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!