使用 Parse 时 GCD 串行队列似乎没有串行执行

Posted

技术标签:

【中文标题】使用 Parse 时 GCD 串行队列似乎没有串行执行【英文标题】:GCD serial queue does not seem to be serially executed when using Parse 【发布时间】:2014-04-28 05:54:06 【问题描述】:

提前感谢您的帮助。我正在尝试创建一个应用程序,允许用户回答问题并为一群人添加自己的问题。我正在从 parse 下载股票问题,出于各种原因,我需要将这些问题以特定顺序加载到主数组中。我正在尝试使用串行 GCD 队列来完成此操作,但这始终在预期结果和相反结果之间切换。这对我来说没有意义,但我无法摆脱这种感觉,即它可能与解析查询中使用的异步下载请求有关,这里没有其他答案可以解决。

这是我的代码:

- (void)viewDidLoad
[super viewDidLoad];


//Load the question with Central Dispatch to ensure load order
dispatch_queue_t my_queue = dispatch_queue_create("com.suresh.methodsqueue", NULL);
dispatch_async(my_queue, ^
    //Load the inital questions
    if (self.objectQuestions == nil) 
        [self loadQuestionsWithClassName:@"FirstHundred"];
    
);
dispatch_async(my_queue, ^
    //Load the paid questions
    [self loadQuestionsWithClassName:@"PaidQuestions"];
);

这是我写的辅助方法:

-(void)loadQuestionsWithClassName:(NSString *)tempString 
//Query from Parse
PFQuery *query = [PFQuery queryWithClassName:tempString];
[query orderByAscending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *firstobjects, NSError *error) 
    if (!error) 
        // The find succeeded. Relay that information.
        NSLog(@"Successfully retrieved %lu items from user %@", (unsigned long)firstobjects.count, [[PFUser currentUser] objectId]);

        //Clear the objectQuestions temporary array and load the new Questions with the QuestionAndAnswers class
        self.objectQuestions = nil;
        self.objectQuestions = (NSMutableArray *)firstobjects;
        int n;
        int x = 0;
        int z = (int)[[MainQuestionList sharedInstance].mainQuestionList count];
        for (n=(int)[[MainQuestionList sharedInstance].mainQuestionList count]; n<[self.objectQuestions count]+z; ++n)
        
            QuestionsAndAnswers *startQuestion = [[QuestionsAndAnswers alloc] init];
            startQuestion.questionNumber = &(n)+1;
            PFObject *object = [self.objectQuestions objectAtIndex:x];
            startQuestion.question = [object objectForKey:@"question"];
            startQuestion.answer = 0;
            startQuestion.starred = NO;
            startQuestion.answered = NO;
            startQuestion.category = [object objectForKey:@"Category"];
            ++x;


            [[MainQuestionList sharedInstance].mainQuestionList addObject:startQuestion];
        

        //Find the first unanswered question
        while ([[MainQuestionList sharedInstance].mainQuestionList[self.mainQuestionNumber] answered] == YES) 
            ++self.mainQuestionNumber;
        ;
     else 
        // Log details of the failure
        NSLog(@"Error: %@ %@", error, [error userInfo]);
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Sorry!" message:@"We are sorry. Something seems to have gone wrong loading the app. Please check your internet connection and restart the app!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
    
];


再次感谢任何帮助!

【问题讨论】:

【参考方案1】:

您在这里所做的是序列化对 Parse 库的异步调用。因此,尽管每个-[PFQuery findObjectsInBackgroundWithBlock:] 都在同步排队,但这些函数本身是异步的。您可以尝试使用同步方法-[PFQuery findObjectsWithError:] 方法,以确保您的方法调用以正确的顺序返回。

【讨论】:

以上是关于使用 Parse 时 GCD 串行队列似乎没有串行执行的主要内容,如果未能解决你的问题,请参考以下文章

GCD 中的并发队列与串行队列

在 GCD 中,串行队列通过异步操作 Swift 同步

GCD编程-串行队列与并发队列

ios多线程操作—— GCD串行队列与并发队列

GCD 异步串行队列 - 可以限制队列大小?

GCD使用 串行并行队列 与 同步异步执行的各种组合 及要点分析