0

「データの更新」という UIBarButtonItem があります。ユーザーがクリックすると、アプリはデータを更新する必要があります。そのボタンをクリックすると、Web サービスが起動され、xml データが取り込まれ、それらは 30000 ~ 40000 レコードのオーダーになります。UI がハングしないようにするために、バックグラウンド スレッドを作成し、そこにロードしました。

- (void)refreshDataAction
{
NSLog(@"Refresh Data");
//Put up an alert box indicating user to wait while data is loading.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Data is Loading"
                                                        message:@"Please wait while data is being refreshed."
                                                       delegate:self
                                              cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil, nil];
alert.tag = 10;
[alert show];
 }

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(@"hit in clickedbuttonatindex alertview at 259");
self.refreshActIndicator.hidden = NO;
[self.refreshActIndicator startAnimating];
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                         (unsigned long)NULL), ^(void) {
    [self getAllCustomerValues];

    NSError *nwerror = nil;
    if (![self.secondMOC save:&nwerror])
    {
        NSLog(@"209 Failed to save second MOC");
    }
    else
    {
        //NSLog(@"saved success");
    }
 });
}

ご覧のとおり、アラート ビューが表示されます。[OK] をクリックすると、ボックスは「黒くなった」ままで、画面にぶら下がっています。7 ~ 8 秒後にボックスが消え、アクティビティ インジケーターのアニメーションが開始されます。私の目標は、このようなものを手に入れることです。1.ユーザーがデータの更新ボタンをクリックします。2.アラートビューが表示されます。3. ユーザーが [OK] をクリックします。4. アラート ボックスが消え、すぐにバックグラウンド スレッドが動作し始め、アクティビティ インジケーターが動作/アニメーション表示されます。

ユーザーは、アクティビティ インジケーターがアニメーション化されている間、待機する必要があることがわかります。では、ユーザーが「OK」をクリックした直後にアプリのアニメーションを開始し、alertview OK が黒くならないようにするにはどうすればよいですか。よろしいですか?さらに詳しい情報が必要な場合は、お問い合わせください。ありがとう

編集: この画面には、その日の最初の読み込み時にバックグラウンド スレッドが動作しています。この前に画面があります。その上に続行ボタンがあり、クリックするとバックグラウンド スレッドが起動し、こことまったく同じことを実行します。

編集2:

 - (void)refreshDataAction
   {
NSLog(@"Refresh Data");
self.txtCustomerSearch.text =@"";
[self cleanUPPreviousLabels];

//Put up an alert box indicating user to wait while data is loading.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Data is Loading"
                                                message:@"Please wait while data is being refreshed."
                                               delegate:self
                                      cancelButtonTitle:@"OK"
                                      otherButtonTitles:nil, nil];
//alert.tag = 10;
//[alert show];
[alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:FALSE];

NSLog(@"hit in willpresenet alertview at 221");
    self.refreshActIndicator.hidden = NO;
    [self.refreshActIndicator startAnimating];
NSLog(@"Dispatching");

//Disable the view and all the other controls
self.txtCustomerSearch.userInteractionEnabled =NO;
self.txtCustomerSearch.enabled =NO;
self.btnSearch.enabled =NO;
self.btnSearch.userInteractionEnabled = NO;
self.scrollView.userInteractionEnabled = NO;
//self.view.userInteractionEnabled =NO;
self.chkButton.enabled = NO;


[self deletePreviousValues]; 

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    NSLog(@"Getting customer values");
    [self getAllCustomerValues];
    NSLog(@"Got customer values");

    NSError *nwerror = nil;
    if (![self.secondMOC save:&nwerror])
    {
        NSLog(@"209 Failed to save second MOC");
    }
    else
    {
        //NSLog(@"saved success");
    }


    self.txtCustomerSearch.userInteractionEnabled = YES;
    self.txtCustomerSearch.enabled =YES;
    self.btnSearch.enabled =YES;
    self.btnSearch.userInteractionEnabled = YES;
    self.scrollView.userInteractionEnabled = YES;
    self.view.userInteractionEnabled =YES;
    self.chkButton.enabled = YES;

    [self.refreshActIndicator stopAnimating];

    NSLog(@"Saved");


});
NSLog(@"Dispatched");

}

4

5 に答える 5

0

この種の UI 通知を簡単にするMBProgressHUD ( https://github.com/jdg/MBProgressHUD ) を使用します。一般に、アトミックBOOL 値をチェックできる、呼び出されるメソッドを指定します。HUD を設置するときに BOOL を設定します。バックグラウンド プロセスが完了すると、BOOL がクリアされ、HUD は自動的に消えます。

于 2013-02-21T20:24:49.353 に答える
0

これはすべてバックグラウンド スレッドで行われていると言います。必ずメイン スレッドで UIAlertView をロードしてください。

//[alert show];
[alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:FALSE];

これでおそらく問題は解決します。非同期呼び出しは実際には実行ループの現在のスレッドで発生しており (バックグラウンド スレッドであるため)、(同じ実行ループで) 表示しようとしているアラート ビューをブロックしています。

于 2013-02-21T23:49:50.347 に答える
0

いくつかの NSLog を追加してハングしている場所を確認し、アクティビティ インジケーターを停止して、ディスパッチが原因でハング全体が発生しているかどうかを確認すると役立つ場合があります。

 NSLog(@"hit in clickedbuttonatindex alertview at 259");
 self.refreshActIndicator.hidden = NO;
 [self.refreshActIndicator startAnimating];
 NSLog(@"Dispatching");
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                     (unsigned long)NULL), ^(void) {
    NSLog(@"Getting customer values");
    [self getAllCustomerValues];
    NSLog(@"Got customer values");

    NSError *nwerror = nil;
    if (![self.secondMOC save:&nwerror])
    {
        NSLog(@"209 Failed to save second MOC");
    }
    else
    {
        //NSLog(@"saved success");
    }
    [self.refreshActIndicator stopAnimating];
    NSLog(@"Saved");
 });
 NSLog(@"Dispatched");

何が起こっているかというと、何らかの理由でメイン (UI) キューが停止しているため、ハングしているように見えます。停止しているため、アニメーションを開始するように指示しても、更新アクティビティ インジケーターなどはアニメーションしません。また、非同期で UI を更新することはできないため、secondMOC を使用してテーブルにデータをリロードさせないでください。[self getAllCustomerValues]; UI の操作を行うべきではありません。

于 2013-02-21T19:55:41.367 に答える
0

変更してみる

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
                                     (unsigned long)NULL), ^(void) {

バックグラウンド優先に

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,
                                     (unsigned long)NULL), ^(void) {
于 2013-02-21T19:22:12.243 に答える
0

alertView:didDismissWithButtonIndex:の代わりに使用しalertView:clickedButtonAtIndex:ます。このようにして、コードが呼び出されたときにアラートはすでに無視されています。

質問 - なぜアラート ビューを気にするのですか? ユーザーは、「更新」アイコンをタップしたことを知っています。アクティビティ インジケーターが既に表示されており、アラートによってユーザーが更新をキャンセルする機会が与えられていません。

更新: dispatch_async の呼び出しは少しずれているようです。これを試して:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self getAllCustomerValues];

    NSError *nwerror = nil;
    if (![self.secondMOC save:&nwerror]) {
        NSLog(@"209 Failed to save second MOC");
    } else {
        //NSLog(@"saved success");
    }
});
于 2013-02-21T19:40:32.697 に答える