2

我正在接受 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]]) 是否满足

4

2 回答 2

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);

于 2013-01-31T04:29:29.223 回答
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);
于 2013-02-23T05:29:13.193 回答