簡體   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