2012-03-21 94 views
1

我检索与UIImagePickerController的图像,我需要检查它是否有gps元数据在它或不。这段代码将把它拉出来,但我在与块的时间有关的问题。因为我在assetLibrary上使用了一个块,所以它会在稍后时间完成(稍微提高一点点)。问题与块,并等待它完成

if ([info objectForKey:UIImagePickerControllerReferenceURL]) 
{ 
    [self performSelectorOnMainThread:@selector(testMethod:) withObject:[info objectForKey:UIImagePickerControllerReferenceURL] waitUntilDone:YES]; 

    NSLog(@"self.metadataDictionary back in impagepickerdidfinish: %@", self.metadataDictionary); 
} 

}

-(void)testMethod:(NSURL *) photoURL 
{   
     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 

     [library assetForURL:photoURL resultBlock:^(ALAsset *asset) { 
      ALAssetRepresentation *representation = [asset defaultRepresentation]; 
      NSDictionary *metadataDict = [representation metadata]; 
      self.metadataDictionary = metadataDict; 
      NSLog(@"self.metadataDictionary in block: %@", self.metadataDictionary); 

     } failureBlock:^(NSError *error) { 
      NSLog(@"%@",[error description]); 
     }]; 
} 

行了块之前

NSLog(@"self.metadataDictionary back in impagepickerdidfinish: %@", self.metadataDictionary); 

2012-03-21 16:40:47.110[9387:707] self.metadataDictionary back in impagepickerdidfinish: (null) 
2012-03-21 16:40:47.265[9387:707] self.metadataDictionary in block: { 
    ColorModel = RGB; 
} 

运行完成并且记录作为(空)。

我以为在主线程上调用它会使它等到块完成,但它不会。

任何想法如何让应用程序等待块完成?

回答

2

assetForURL:resultBlock:failureBlock:未被同步调用,如NSArrayenumerateObjectsUsingBlock:。这更像是使用dispatch_async - 该块将被调用,但不一定马上。

我会做的是创建另一个方法,您的结果块调用让其他应用程序知道一切都已完成。我不相信有什么办法让这个呼叫阻塞线程直到完成 - 而且也不应该有:

When the ALAsset is requested, the user may be asked to confirm the application's access to the data. 

你不想阻塞主线程的其余部分,而用户确认或否认访问您的应用程序。这就是为什么它是一个异步调用。

+0

有一种方法可以等待块被调用。你所要做的就是手动运行运行循环,并让块设置一个变量来表明它已完成。这会让其他事件在不返回时处理。 – ughoavgfhw 2012-03-21 22:02:20

+1

你*可以*,但这是一个坏主意。 Apple设计他们的API,以便这些类型的长时间运行的操作不会阻塞主线程。当你可以从'resultBlock'参数中调用一个方法时,为什么要绕过这种设计? – 2012-03-21 22:05:59

+0

+1不要阻止主线程! GUI和所有那些 – 2012-03-21 23:46:50