Iphone 无法理解同步方法、块和GCD

Iphone 无法理解同步方法、块和GCD,iphone,objective-c,ios,cocoa-touch,objective-c-blocks,Iphone,Objective C,Ios,Cocoa Touch,Objective C Blocks,我有以下一段代码,它使用ALAssets库将用户相册存储在一个数组中,这样它就可以像photos应用程序一样将用户相册填充到一个表中: - (void) loadAlbums { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [[self activityIndicator] startAnimating]; [[self library] enumerateGroupsWithTypes:ALA

我有以下一段代码,它使用ALAssets库将用户相册存储在一个数组中,这样它就可以像photos应用程序一样将用户相册填充到一个表中:

- (void) loadAlbums
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [[self activityIndicator] startAnimating];

    [[self library] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
    {
        if (group == nil)
        {
            [[self activityIndicator] stopAnimating]; 
            [[self tableView] reloadData];

            return;
        }

        [[self albums] addObject:group];
    }
    failureBlock:^(NSError *error) 
    {
        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Album Error: %@", [error description]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }];

    [pool release];
}
据我所知,
enumerateGroupsWithTypes
是一种异步方法,这意味着它在自己的线程上运行。但是,block参数在主线程上运行。 代码在顶部,我的活动指示器有问题。当包含此方法的
viewcontroller
第一次运行时,
activityindicator
工作正常,但是如果我将
viewcontroller
从堆栈中弹出(即按下后退按钮)并再次重新加载,则活动指示器不会出现(尽管我正在玩
ishiden
等)。所以我有一些问题:

1) 有人知道活动指示器可能存在什么问题吗

2) 除了使用
[NSThread sleepWithDuration]
NSTimer
之外,在不创建包含大量图片的相册的情况下模拟缓慢加载时间的最佳方法是什么

3) 如果加载照片确实需要一段时间,我的应用程序的UI是否会被阻止,或者用户是否仍然能够与之交互?因为它是在一个单独的线程上运行的,所以它似乎应该运行,但我不是很确定

更新:关于如何更好地利用这一点,有什么想法或资源吗?我读过苹果的线程编程和并发技术,看过很多WWDC的视频,但我仍然很难理解如何处理像这样的简单情况,我只是试图不阻止用户使用UI

据我所知,enumerateGroupsWithTypes是一个异步方法,这意味着它在自己的线程上运行

“异步”并不意味着“在自己的线程上运行”。在iOS中,异步有几种方式。最常见的方法之一是使用run循环。这并不是说这个方法不生成线程;可能吧。但是没有理由假设它是这样的,如果是这样的话,这是一个私有的实现细节。正如您所说,您的块在主线程上运行,这是您在这里真正关心的唯一事情

从您描述的症状来看,我怀疑这与此代码有关。这听起来更像是视图加载代码的错误。我将检查例程
loadView
viewDidLoad
initWithFrame:
awakeFromNib
视图将出现:
,以及
viewdidisped:
。很可能您在错误的位置创建了进度指示器,或者未能将其插入视图层次结构,或者将其从视图层次结构中删除


关于模拟缓慢加载时间,我建议使用“大量图片”方法。您应该能够以编程方式生成大量图片(甚至可以反复复制相同的图片),所以这应该不会太糟糕。如果是您的个人设备,这有点令人讨厌,但这就是开发的本质。

为什么您认为枚举是异步进行的?在这个方法的文档中,我没有看到任何迹象。@kevin ballard-文档中说“这个方法是异步的。”嗯,我们一定在看不同版本的文档。你是对的,确实是这样说的。你验证过块实际上是在主线程上执行的吗?我在文档中看不到这方面的保证。@kevin ballard-是的,我使用了NSLog(@“On main thread:%d”,[NSThread isMainThread]?1:0)+1仅针对
“异步”并不意味着“在自己的线程上运行”。
。并不是说你剩下的答案不正确,只是我一直看到这个
async==不同的线程
逻辑。