【问题标题】:making asynchronous blocks run before other code使异步块在其他代码之前运行
【发布时间】:2012-07-31 23:27:51
【问题描述】:

我正在尝试从 ALAssetLibrary 获取视频,以便我可以用它做一些事情。我正在使用积木来做到这一点:

NSMutableArray *assets = [[NSMutableArray alloc] init];

library = [[ALAssetsLibrary alloc] init];

NSLog(@"library allocated");

// Enumerate just the photos and videos group by using ALAssetsGroupSavedPhotos.

[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {

    NSLog(@"Begin enmeration");

    [group setAssetsFilter:[ALAssetsFilter allVideos]];

    NSLog(@"Filter by videos");

    [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets]-1]

                            options:0

                         usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {

                             NSLog(@"Asset retrieved");

                             if (alAsset) {

                                 ALAssetRepresentation *representation = [alAsset defaultRepresentation];

                                 NSURL *url = [representation url];

                                 AVAsset *recentVideo = [AVURLAsset URLAssetWithURL:url options:nil];

                                 [assets addObject:recentVideo];

                                 NSLog(@"Asset added to array");

                             } 
                         }];
}

AVMutableComposition *composition = [[AVMutableComposition alloc] init];

NSLog(@"creating source");
AVURLAsset* sourceAsset = [assets objectAtIndex:0];

当我运行代码时,块被跳过,当我尝试访问数组中的元素时程序崩溃,因为它不存在。有人告诉我这是因为这些块是异步的,但我不确定如何让它们在其他所有操作之前运行。 performSelectorOnMainThread 听起来它可能会这样做,但我真的找不到任何解释我将如何这样做的东西。

【问题讨论】:

    标签: objective-c ios xcode


    【解决方案1】:

    如果你愿意

    AVMutableComposition *composition = [[AVMutableComposition alloc] init];
    
    NSLog(@"creating source");
    AVURLAsset* sourceAsset = [assets objectAtIndex:0];
    

    在枚举group之后发生,然后将其放在第一个Block中,但在枚举之后:

    AVMutableComposition *composition = [[AVMutableComposition alloc] init];
    __block AVURLAsset* sourceAsset = nil;
    [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    
        // snip...
    
        [group enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:[group numberOfAssets]-1]
                                options:0
                             usingBlock:^{
                                 // snip... 
                             }];
        sourceAsset = [assets objectAtIndex:0];
        // Now do other things that depend on sourceAsset being set 
    }];
    

    __block 关键字允许将指针设置为块内的新对象;否则变量不可重新赋值。

    【讨论】:

    • 我确实需要它,但还有一堆其他代码也必须在它之后运行。我认为最好尝试将枚举放入它自己的函数中,在那里我还分配源资产,然后做所有其他的事情,但我担心即使我把它放入一个函数中它仍然会表现得很奇怪。不过,我想我永远不会知道,直到我尝试。
    猜你喜欢
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多