2016-05-27 6 views
0

Xcodeのバージョンは表示されません:私はせずに「ロード中...しばらくお待ちください」のメッセージを示してiPad上UIAlertController警告メッセージを表示しようとしています9.1+UIAlertControllerはすぐ

:、iOSのバージョンを7.2.1にボタンを押します。私は長い操作を開始する前にUIAlertControllerを提示してから、長い操作の後にUIAlertControllerを閉じます。 しかし、何が起こっているのかは、UIAlertControllerが即座に表示されないことです。それは、長い操作が完了した後に短時間だけ点滅し、それが解消されます。

は、一般コード構造次の通りである:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert]; 
    [self presentViewController:alert animated:YES completion:nil]; 

    /// Perform long operation here... 
    /// (Basically, a message is being sent to a server, a long operation happens on 
    /// the server, and then the server returns a response to the iPad client.) 

    [alert dismissViewControllerAnimated:YES completion:nil]; 
} 

私は長い操作が行われている間、警告メッセージを同時に表示することができるようにdispatch_async用いて同様に、選択肢の数を試みた:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert]; 
    [self presentViewController:alert animated:YES completion:nil]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{   

     /// Perform long operation here... 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      [alert dismissViewControllerAnimated:YES completion:nil]; 
     }); 
    }); 
} 

私はUIAlertView(私はiOS 8で推奨されていないことがわかっています)を、単独でもディスパッチでも試してみましたが、どちらも動作していません。

performSelectorメッセージで長い操作コードをラップしようとしましたが、役に立たないです。

以前は、この状況では、ディスパッチキューを持つUIAlertViewをシームレスに使用していました。

ご協力いただければ幸いです。

編集:

一つ注意す興味深い:dispatch_asyncコードでは、私は右のロングオペレーションコードを呼び出す前にはusleep(250000)を追加した場合、時間の約80%、UIAlertControllerの警告メッセージ正しい時間に表示されます:長い操作が始まる前に。しかし、これは100%の時間ではなく、持続可能な解決策ではありません。小さい番号で謝辞を呼び出すことはできません。

DISPATCH_QUEUE_PRIORITY_DEFAULTオプションのために、私も試したこと注: DISPATCH_QUEUE_PRIORITY_HIGH、DISPATCH_QUEUE_PRIORITY_LOW、およびDISPATCH_QUEUE_PRIORITY_BACKGROUND

そして、私が試した、あまりにも次

dispatch_queue_t myQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); 

dispatch_async(myQueue, ^{ 
    /// Perform long operation here... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [alert dismissViewControllerAnimated:YES completion:nil]; 
    }); 
}); 
+0

あなたの第二の変形が正しいか、あなたは長い操作の詳細コードを投稿する必要があります。長い操作の中のどこかでメインスレッドをブロックしている可能性があります。それはまさにこの問題を引き起こすでしょう。 – Sulthan

+0

@Sulthanはい、長い操作コードで、私は**と** recv **データを送信するためにTCPソケットを使用しています。 ** recv **ソケット関数は、サーバーからデータを受け取るまでブロックします。 – silverness

+0

問題ではないように、バックグラウンドスレッド(2番目のバージョン)で実行しています。私はあなたが何とかメインスレッドをブロックしていると思います。 – Sulthan

答えて

0

、dismissViewControllerメソッドが呼び出されませんでしたので、AlertViewControllerメッセージだけでハングアップするいくつかのケースがありました。 (おそらく、さまざまなスレッドの競合状態...私は確信しています。)したがって、最終的に確実に動作するように見え、きれいな解決策に見えるのは、AlertViewControllerの完了ブロックとdispatch_after呼び出しの組み合わせを使用することです。

iOS referenceからの完了呼び出しの詳細:「完了ハンドラは、表示されたビューコントローラでviewDidAppear:メソッドが呼び出された後に呼び出されます。

This postは援助であった。)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    // Initialize the alert view controller. 
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert]; 

    // Present the alert view controller. 
    [self presentViewController:alert animated:YES completion:^{ 

     /// Perform long operation here... 

     dispatch_after(0, dispatch_get_main_queue(), ^{ 

      // Dismiss the alert message. 
      [loadAlertController dismissViewControllerAnimated:YES completion:nil]; 

      /// Execute rest of code INDSIDE the dispatch code block INSTEAD of after it... 
     }); 
    }]; 
} 
0

CFRunLoopWakeUp(CFRunLoopGetCurrentを())だけ入れてみてくださいアラートコントローラを表示すると、以下のようになります。

+0

提案していただきありがとうございます。私はちょうど両方のケース(ディスパッチの有無にかかわらず)を試みましたが、動作しませんでした...同じ動作を示しています。 – silverness

+0

私はこの答えを提案しました。あなたがメインスレッドにいない可能性があるからです。そのために遅延があります。 –

0

結局のところ、ディスパッチコードとCFRunLoopWakeUpコール(@Bhavuk Jainが提案)の組み合わせがありました。私がやらなければならなかったのは、元の投稿に表示されなかったディスパッチブロックの後のコードを、ディスパッチブロックのINSIDEに移動することでした。だから、次は、これまでに取り組んでいる:

私は答え(5月31日)としてマークされたオリジナルのポストで
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    // Initialize and present the alert view controller. 
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert]; 
    [self presentViewController:alert animated:YES completion:nil]; 

    // Force wake up the run loop. 
    CFRunLoopWakeUp(CFRunLoopGetCurrent()); 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{   

     /// Perform long operation here... 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      [alert dismissViewControllerAnimated:YES completion:nil]; 

      /// Execute rest of code INDSIDE the dispatch code block INSTEAD of after it... 
     }); 
    }); 
} 
関連する問題