等待assetForURL块完成

Mat*_*ieu 24 iphone objective-c alasset alassetslibrary

我想等待这个代码继续执行之前继续但是因为这些块被异步调用我不知道该怎么做???

NSURL *asseturl;
NSMutableArray *tmpListAsset = [[NSMutableArray alloc] init];

ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
NSMutableArray *objectsToRemove = [[NSMutableArray alloc] init];
for (NSDictionary *dico in assetsList) {
    asseturl = [NSURL URLWithString:[dico objectForKey:@"assetUrl"]];
    NSLog(@"asset url %@", asseturl);
    // Try to load asset at mediaURL
    [library assetForURL:asseturl resultBlock:^(ALAsset *asset) {
        // If asset doesn't exists
        if (!asset){
            [objectsToRemove addObject:dico];
        }else{
            [tmpListAsset addObject:[asseturl absoluteString]];
            NSLog(@"tmpListAsset : %@", tmpListAsset);
        }
    } failureBlock:^(NSError *error) {
        // Type your code here for failure (when user doesn't allow location in your app)
    }];
}
Run Code Online (Sandbox Code Playgroud)

Cha*_*ski 44

GCD信号量方法:

dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

for (NSURL *url in self.assetUrls) {
    dispatch_async(queue, ^{
        [library assetForURL:url resultBlock:^(ALAsset *asset) {
            [self.assets addObject:asset];
            dispatch_semaphore_signal(sema);
        } failureBlock:^(NSError *error) {
            dispatch_semaphore_signal(sema);
        }];
    });
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
dispatch_release(sema);

/* Check out ALAssets */
NSLog(@"%@", self.assets);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果不应在后台线程中调用此代码(例如:使用`performSelectorInBackground:`),则会发生死锁(这些块似乎在同一个线程上被调用,因此信号量永远不会发出信号). (4认同)

Mat*_*ieu 6

解决方案在这里 http://omegadelta.net/2011/05/10/how-to-wait-for-ios-methods-with-completion-blocks-to-finish/

  • 这是一个仅限链接的答案,应该通过包括源文章中的相关代码和现代化来改​​进(因为这个答案现在已经有4年了). (2认同)