繁体   English   中英

iOS Objective-C 等待异步进程

[英]iOS Objective-C wait for async process

我正在从 AppDelegate 中调用以下代码:

-(void) application:(UIApplication *)application performFetchWithCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {


-(BOOL)backgroundRefresh{
    newData = false;
    callStartTime = [NSDate date];

    [self processAll];
       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        while(!fetchComplete);
        NSLog(@"NOW COMPLETE");

   });
    NSLog(@"Got here now!");
    return newData;
}

对 [self processAll] 的调用运行具有异步调用等的代码,并将继续循环直到所有活动完成,重复调用自身。 完成所有任务后,fetchComplete 将设置为 true。 这部分工作正常。

我需要代码等待 fetchComplete 为真,然后将布尔值返回给 AppDelegate。

问题是,非常正确的是,当前检查虽然可以显示 NSLogs 等,但对于将 BOOL 返回给调用者毫无用处,因为该进程当前是异步的。 我已经将它设置为 async 以便它运行,否则,我发现 processAll 代码被阻止运行。

有人可以解释一下我如何监视 fetchComplete,并且只有在这种情况下才将 bool 返回给调用函数吗?

在 while 返回后,我尝试将 return 移动到异步块中,但是由于在块内调用,这会返回语法错误。

使用通知。 首先,您必须像这样开始收听通知

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(fetchDidComplete)
                                             name:@"fetchDidComplete"
                                           object:nil];

无论何时将 fetchComplete 设置为 true,请发布这样的通知

[[NSNotificationCenter defaultCenter] postNotificationName:@"fetchDidComplete"
                                                    object:self
                                                  userInfo:nil];

然后你应该有一个名为 fetchDidComplete 的方法来完成后完成工作。 完成后不要忘记停止收听通知。

[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:@"fetchDidComplete"
                                              object:nil];

您无需等待异步进程完成。 这使它同步。 你需要改变你的想法。

有多种不同的方式来处理异步 API。

  1. 传入一个完成块
  2. 分配一个委托并定义一个在完成时调用的方法。
  3. 进程完成时发送通知。

毫无疑问,异步 API 的整个想法是它立即返回,而不是等待它完成。 正如另一个人所说,永远不要使用像while(!fetchComplete)这样的代码。 这是一个非常糟糕的主意。

你试图解决这个问题的庄园有点不典型。

通常这是通过委托、 blocksnotifications

这个想法是你只想在完成一些异步方法后执行一些function

假设我们有一个名为AyncProcessor的异步处理器。

AyncProcessor * processor = [AyncProcessor sharedProcessor];
processor.delegate = self;
[processor start];

是一种相当常见的方式来做委托。 这里的假设是有一个协议定义了一个回调方法,该方法在完成时运行。

//protocol method
-(void) processingComplete;

// and at some point in AsyncProcessor
[self.delegate processingComplete] 

关于代表团的更多信息在这里

块也可以使用

AyncProcessor * processor = [AyncProcessor sharedProcessor];
[processor start:^()/{
  ///code in this block will complete after processing has completed
 }];

可以在此处找到有关块的更多信息

正如已经显示的那样,您可以发送NSNotification

对于您的问题,委托可能是一个好主意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM