我正在接受stanford cs 193 p assignment5。问题在于,当我将数据传送到目标视图控制器并使用调度队列来获取viewDidLoad方法中的数据时,dispatch_async不会在目标视图控制器中执行。这里是我的视图控制器A和目标视图控制器的代码。
查看控制器A代码
-(void)viewDidLoad
{
[super viewDidLoad];
if(!self.places){
self.spinner.hidesWhenStopped = YES;
self.spinner.center = self.tableView.center;//
[self.view addSubview:self.spinner];
[self.spinner startAnimating];
dispatch_queue_t dispatchQueue = dispatch_queue_create("queue_top_places", NULL);
dispatch_async(dispatchQueue, ^{
self.places = [self getRecentPlacesFromFlicker];
// main queue to load table view data
dispatch_async(dispatch_get_main_queue(), ^{
// load table data
if(self.tableView.window){
[self.tableView reloadData];
[self.spinner stopAnimating];
}
});
});
dispatch_release(dispatchQueue);
}
// Uncomment the following line to preserve selection between presentations.
self.clearsSelectionOnViewWillAppear = YES;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"Show Recent Photo List"]){
int currentRow = self.tableView.indexPathForSelectedRow.row;
// set up photo list controller model
[segue.destinationViewController setPhotosList:[self.places objectAtIndex:currentRow]];
}
}
这是我的目标视图控制器代码
- (void)viewDidLoad
{
[super viewDidLoad];
// get the current top place name and fetch photos at that place from flicker
if ([self.photosList isKindOfClass:[NSDictionary class]])
{
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.hidesWhenStopped = YES;
spinner.center = self.tableView.center;//
[self.view addSubview:spinner];
[spinner startAnimating];
dispatch_queue_t dispatchQueue1 = dispatch_queue_create("queue_top_50_photos", NULL);
dispatch_async(dispatchQueue1, ^{
self.photosList = [FlickrFetcher photosInPlace:self.photosList maxResults:50];
dispatch_async(dispatch_get_main_queue(), ^{
if (self.tableView.window ){
[self.tableView reloadData];
[spinner stopAnimating];
}
});
});
dispatch_release(dispatchQueue1);
}
// Uncomment the following line to preserve selection between presentations.
self.clearsSelectionOnViewWillAppear = YES;
self.title = @"50PhotoList";
}
使用调试器检查条件([self.photosList isKindOfClass:[NSDictionary class]])
答案 0 :(得分:3)
我刚考虑过这个问题,您是否尝试在viewDidAppear
而不是viewDidLoad
中运行此代码?我试试看。
为每个操作创建新队列的任何原因?如果您最后删除dispatch_release
指令怎么办?也许您的异步操作所需的时间比释放队列的时间要长。
尝试使用全局队列而不是您自己创建的队列,在完成后不必释放。
替换
dispatch_queue_t dispatchQueue1 = dispatch_queue_create("queue_top_50_photos", NULL);
与
dispatch_queue_t dispatchQueue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
并删除dispatch_release(dispatchQueue1);
答案 1 :(得分:0)
dispatch_async立即返回并在后台执行任务,并在viewDidLoad或其他viewDidAppear方法中执行其余代码。
一种解决方案是使用dispatch_sync,它等待执行任务并将其嵌套在dispatch_async中,如下所示
dispatch_queue_t dispatchQueue1 = dispatch_queue_create("queue_top_50_photos", NULL);
dispatch_async(dispatchQueue1, ^{
dispatch_queue_t dispatchSyncQueue = dispatch_queue_create("queue_top_50_photos", NULL);
dispatch_sync( dispatchSyncQueue,^){
self.photosList = [FlickrFetcher photosInPlace:self.photosList maxResults:50];
});
dispatch_sync(dispatch_get_main_queue(), ^{
if (self.tableView.window ){
[self.tableView reloadData];
[spinner stopAnimating];
}
});
dispatch_release(dispatchSyncQueue);
});
dispatch_release(dispatchQueue1);