0

所以我有一个准备代码块并安排它在串行调度队列上同步运行的函数。我知道这个串行队列将在一个新线程上运行。然而,问题在于代码块修改了一个变量,该变量将其传递回函数,而函数又期望将其作为返回值返回。下面的代码将有助于澄清情况:

-(DCILocation*) getLocationsByIdentifier: (NSString*) identifier andQualifier: (NSString*) qualifier {

    __block DCILocation* retval = nil;

    NSString* queryStr = [self baseQueryWithFilterSet:nil];
    queryStr = [queryStr stringByAppendingString:@" (identifier = ? OR icao = ?) AND qualifier = ?"];

   [self.queue inDatabase:^(FMDatabase *db) {
        FMResultSet* results = [db executeQuery:queryStr,
                               [identifier uppercaseString],
                               [identifier uppercaseString],
                               [qualifier uppercaseString]];
        if ((nil != results) && [results next]) {
             dispatch_async(dispatch_get_main_queue(), ^{
                 retval = [DCIAirportEnumerator newAirportForStatement:results];
             });
            [results close];
        }
   }];

   return retval;
}

“self.queue”是块将在其上运行的串行调度队列。请注意,该块修改了“retval”并通过将 dispatch_async 调用嵌套到主线程来更新它。然而,令人担忧的是,在串行调度队列上运行的代码块能够修改它之前,可能会调用“return retval”(函数的最后一行)。这将导致返回“nil”。

关于如何确保函数在 retval 被串行队列上执行的块修改之前不会返回的任何想法?

4

2 回答 2

4

关于如何确保函数在 retval 被串行队列上执行的块修改之前不会返回的任何想法?

如果您需要等待结果,那么您的代码仍然是同步的,您不妨在您的方法中而不是在串行队列中运行它。所以这是第一个选择:不要在这里使用块。

第二种选择是重构您的代码,使其真正异步运行。找到依赖于返回值的代码retval并将其分解为单独的方法或块。然后让设置retval调用的块在retval完成时传入。

于 2013-01-03T15:53:43.843 回答
-2

在你的块之后,你可以添加

while(YES) {
    if(variable) {
        break;
    }
}

然后在dispatch_async定义 retval之后添加

variable = YES;

您只需要 __block BOOL variable = NO;在块之前定义。

于 2013-01-03T15:48:46.133 回答