问题 如何使用块为我的整个应用程序共享的每个磁盘上的文档创建一个全局UIManagedDocument实例?


我正在尝试设计一个帮助方法,它将检索UIManagedDocument,然后打开并返回它,以便我可以从我的应用程序中的几个位置访问相同的UIManagedDocument。

我对这种异步性质有困难,因为我对块不太熟悉。理想情况下,事件的顺序是这样的:

  1. 类X调用helper方法来检索UIManagedDocument,并包含一个在返回打开的文档时运行的代码块。
  2. 类方法检索UIManagedDocument并根据需要调用openWithCompletionHandler或saveToURL,并包含在返回打开的文档时运行的代码块。
  3. openwithCompletionHandler或saveToURL完成他们的任务,并返回成功= YES并在其块中运行代码
  4. 类方法完成其任务并返回一个打开的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
        }];

    }

}

10339
2018-02-09 00:56


起源



答案:


您可以使用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方法的类中实现了以下方法:

-(void)vacationOpened:(UIManagedDocument *)vacation
{
    NSLog(@"My Vacation: %@", vacation.description);
}

调用openVacation方法的示例代码行将是:

[MyVacationsHelper openVacation:@"MyVacation1" usingBlock:^(UIManagedDocument *vacation){
    [self vacationOpened:vacation];
}];

插入符号后的(UIManagedDocument * vacation)意味着当您使用括号表示法执行块时 - 如 completionBlock(DOC)  - ,您需要列出(UIManagedDocument *)作为参数。该参数的值将被称为 假期 在指定的块内。我在上面的块代码示例中所做的是在我当前的类中调用一个方法(self)并将参数传递给该方法,以便我可以根据需要使用它(我只是在这里做了一个NSLog以确保它工作) 。


7
2018-02-09 04:04



将它捣毁出公园,干得好,像梦一样! - Alan


答案:


您可以使用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方法的类中实现了以下方法:

-(void)vacationOpened:(UIManagedDocument *)vacation
{
    NSLog(@"My Vacation: %@", vacation.description);
}

调用openVacation方法的示例代码行将是:

[MyVacationsHelper openVacation:@"MyVacation1" usingBlock:^(UIManagedDocument *vacation){
    [self vacationOpened:vacation];
}];

插入符号后的(UIManagedDocument * vacation)意味着当您使用括号表示法执行块时 - 如 completionBlock(DOC)  - ,您需要列出(UIManagedDocument *)作为参数。该参数的值将被称为 假期 在指定的块内。我在上面的块代码示例中所做的是在我当前的类中调用一个方法(self)并将参数传递给该方法,以便我可以根据需要使用它(我只是在这里做了一个NSLog以确保它工作) 。


7
2018-02-09 04:04



将它捣毁出公园,干得好,像梦一样! - Alan


我发现了一篇非常有用的文章 - “具有单个共享UIManagedDocument的核心数据


3
2017-10-17 03:28



作者不再建议使用uimanageddocument执行此操作。 - smileBot