dispatch_queue没有执行

时间:2013-01-31 04:14:54

标签: ios objective-c grand-central-dispatch

我正在接受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]])

2 个答案:

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