我有以下代码片段,它使用ALAssets库将用户相册存储到一个数组中,以便它们可以像照片应用程序一样填充在表格中:
- (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
(即按下后退按钮)并重新加载它,活动指示器没有出现(尽管我在玩isHidden
等)。所以我有一些问题:
1)任何人都能了解活动指标可能出现的问题吗?
2)除了使用[NSThread sleepWithDuration]
和NSTimer
之外,什么是模拟慢加载时间而不必创建包含大量图片的相册的最佳方式?
3)如果加载照片确实需要一段时间,我的应用的用户界面会被阻止,还是用户仍然可以与之互动?因为它在一个单独的线程上运行,所以它似乎应该,但我不确定。
更新:有关如何改善这一点的任何想法或资源?我已经阅读了Apple的线程编程和并发人员并观看了很多WWDC视频,但我仍然无法掌握如何处理这样的绝对简单的情况,我只是试图不阻止用户的UI。
答案 0 :(得分:3)
据我所知,enumerateGroupsWithTypes是一个异步方法,这意味着它在自己的线程上运行。
“异步”并不意味着“在自己的线程上运行”。在iOS中有几种异步方式。其中最常见的是使用run循环。这并不是说这种方法不会生成线程;它可能。但没有理由认为它确实如此,如果确实如此,那就是私有的实现细节。正如你所说,你的块在主线程上运行,这是你唯一应该关注的事情。
根据您描述的症状,我怀疑它与此代码有什么关系。这听起来更像是您加载代码的视图中的错误。我会检查例程loadView
,viewDidLoad
,initWithFrame:
,awakeFromNib
,viewWillAppear:
和viewDidAppear:
。您很可能在错误的位置创建进度指示器,或者未将其插入到视图层次结构中,或者从视图层次结构中删除它。
关于模拟慢加载时间,我建议使用“大量图片”方法。您应该能够以编程方式生成大量图片(您甚至可以反复复制相同的图片),所以这不应该太糟糕。如果它是你的个人设备有点烦人,但这就是开发的本质。