11

UIManagedDocument を取得し、それを開いて返すヘルパー メソッドを設計しようとしています。これにより、アプリの複数の場所から同じ UIManagedDocument にアクセスできるようになります。

私はブロックに慣れていないので、これの非同期性に問題があります。理想的には、一連のイベントは次のようになります。

  1. クラス X はヘルパー メソッドを呼び出して UIManagedDocument を取得し、開かれたドキュメントが返されたときに実行するコード ブロックを含めます。
  2. クラス メソッドは UIManagedDocument を取得し、必要に応じて openWithCompletionHandler または saveToURL を呼び出し、開いたドキュメントが返されたときに実行するコード ブロックを含めます。
  3. openwithCompletionHandler または saveToURL がタスクを完了し、success = 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
        }];

    }

}
4

2 に答える 2

7

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) は、( UIManagedDocument *) をパラメーターとしてリストする必要があることを意味します。そのパラメータの値は、指定されたブロック内で休暇として参照されます。上記のブロック コード サンプルで行ったことは、現在のクラス (self) でメソッドを呼び出し、そのメソッドにパラメーターを渡して、必要に応じて使用できるようにすることでした (動作を確認するために、ここで NSLog を実行しました)。 .

于 2012-02-09T04:04:06.500 に答える
3

非常に役立つ記事を見つけました - 「単一の共有 UIManagedDocument を使用したコア データ

于 2012-10-17T03:28:57.010 に答える