我是iOS开发的新手,我遇到了问题。我正在使用来自https://github.com/cwRichardKim/TinderSimpleSwipeCards
的代码为应用程序实现Tinder(如滑动功能)这是我给你带来麻烦的代码。
imageCard = [[NSMutableArray alloc]init];
PFQuery *query = [PFQuery queryWithClassName:@"Post"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (objects != nil) {
NSMutableArray *imageDataArray = [[NSMutableArray alloc] init];
for (PFObject *object in objects) {
// add all image objects into imagesArray
[imageDataArray addObject:object[@"content"]];
}
// loop through imageDataArray and get each image
for (int i = 0; i < [imageDataArray count]; i++) {
PFFile *imageFile = imageDataArray[i];
[imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
NSLog(@"loop: %d",i);
[imageCard addObject:[UIImage imageWithData:data]];
// ***** only loadCards after all images have been retrieved
if (i == [imageDataArray count] - 1) {
loadedCards = [[NSMutableArray alloc] init];
allCards = [[NSMutableArray alloc] init];
cardsLoadedIndex = 0;
NSLog(@"Cards loaded");
[self loadCards];
}
}
}];
}
}
}];
所以我正在查询Post表中所有图像的Parse。然后我将所有图像数据放在imagesArray中。然后我循环使用imagesArray并从后台线程中的图像数据中获取实际图像,并将实际图像放入另一个数组(imageCard)。将所有图像添加到imageCard后,我想加载卡片([self loadCards])。
假设imageDataArray有6个对象。现在的问题是getDataInBackgroundWithBlock异步运行6次。我只想在加载最后一个对象时加载[self loadCards],但最后一个对象可以在其他对象之前加载。这是一个视觉问题的控制台输出。
正如你所看到的,数据没有按升序加载,它是随机加载的,并且“加载卡片”之后的任何内容都没有加载,这就是我需要帮助的问题。
谢谢!
答案 0 :(得分:0)
您的问题正如您所指出的那样,异步任务将以未定义的顺序完成。 Grand Central Dispatch(GCD)使用调度组为waiting for a number of asynchronous tasks to complete提供了解决方案。
要使用它,您需要将异步Parse方法getDataInBackgroundWithBlock
替换为同步版本getData
,并自行将任务分派到异步队列中 -
imageCard = [[NSMutableArray alloc]init];
PFQuery *query = [PFQuery queryWithClassName:@"Post"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (objects != nil) {
NSMutableArray *imageDataArray = [object valueForKey:@"content];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
// loop through imageDataArray and get each image
for (PFFile *imageFile in imageDataArray) {
dispatch_group_async(group, queue, ^{
NSData *data=[imageFile getData]
if (data!=nil) {
NSLog(@"loop: %d",i);
[imageCard addObject:[UIImage imageWithData:data]];
}
});
}
// When you cannot make any more forward progress,
// wait on the group to block the current thread.
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// Release the group when it is no longer needed.
dispatch_release(group);
loadedCards = [[NSMutableArray alloc] init];
allCards = [[NSMutableArray alloc] init];
cardsLoadedIndex = 0;
NSLog(@"Cards loaded");
[self loadCards];
}
}];