0

このコードを使用して、Webサービスからデータをダウンロードしているときにビューの1つにMBProgressHUDを表示していますが、唯一の問題は、このコードによってアプリがハングし、HUDが表示されている間は何もしないことです。 「ダウンロード中」で画面がロックされます。また、更新ボタンを押したときにキーボードのようなものがユーザーに表示されている場合(更新ボタンはダウンロードを実行します)、アプリケーションは次の行でクラッシュします。

 [self.tableView reloadData];

私のコード:

//Checks for network connection then displays HUD while executing pullAndDisplayData method
- (IBAction) update {
    UIAlertView *errorView;

    if([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) {
        errorView = [[UIAlertView alloc] 
                     initWithTitle: @"Network Error" 
                     message: @"No Network connection availible!" 
                     delegate: self 
                     cancelButtonTitle: @"OK" otherButtonTitles: nil]; 
        [errorView show];
    }
    else
    {
        HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
        [self.navigationController.view addSubview:HUD];

        HUD.delegate = self;
        HUD.labelText = @"Downloading";
        HUD.minSize = CGSizeMake(135.f, 135.f);

        [HUD showWhileExecuting:@selector(pullAndDisplayData) onTarget:self withObject:nil animated:YES];
    }
}

//Downloads this users data from the web-service
- (void) pullAndDisplayData{
    // Indeterminate mode
    ExpensesDataDownloader *downloader = [[ExpensesDataDownloader alloc] init];
    [downloader pullAndDisplayData];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([[defaults objectForKey:@"canExportCSVServer"] isEqualToString:@"1"])
    {

    }

    [self.tableView reloadData];

    // Switch to determinate mode
    HUD.mode = MBProgressHUDModeDeterminate;
    HUD.labelText = @"Updating";
    float progress = 0.0f;
    while (progress < 1.0f)
    {
        progress += 0.01f;
        HUD.progress = progress;
        usleep(15000);
    }
    // The sample image is based on the work by www.pixelpressicons.com, http://creativecommons.org/licenses/by/2.5/ca/
    // Make the customViews 37 by 37 pixels for best results (those are the bounds of the build-in progress indicators)
    HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
    HUD.mode = MBProgressHUDModeCustomView;
    HUD.labelText = @"Completed";
    sleep(2);
}

どんな助けでも大歓迎です。

ジャック

4

3 に答える 3

2

pullAndDisplayDataメソッドは別のスレッドで実行されています。これは、MBProgressHUDUIスレッドを使用して自分自身を表示できるようにするためです。常にメイン(UI)スレッドからUIを更新する必要があります。メソッドを使用して、その他のUIperformSelectorOnMainThread:を呼び出します。同期呼び出し[self.tableView reloadData];だと思います。[downloader pullAndDisplayData];

于 2012-07-10T10:58:24.327 に答える
1

MBprogressHUDAPIから

/** 
 * Shows the HUD while a background task is executing in a new thread, then hides the HUD.
 *
 * This method also takes care of autorelease pools so your method does not have to be concerned with setting up a
 * pool.
 *
 * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread.
 * @param target The object that the target method belongs to.
 * @param object An optional object to be passed to the method.
 * @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will not use
 * animations while (dis)appearing.
 */
- (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated;

このメソッドを使用しているため、pullAndDisplayDataは新しいスレッドで実行されます。これはあなたが持っている奇妙な問題を引き起こす可能性があります(私は推測します)。バックグラウンドスレッドからUI要素を更新していますが、これは適切ではありません。UI要素はメインスレッドから更新されます。データのみをダウンロードするには、バックグラウンドスレッドを使用します。

それを使用することのはめ込み、GCD(Grand Central Dispatch)を使用してみてください

[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    // download operation here...
    dispatch_async(dispatch_get_main_queue(), ^{
        [MBProgressHUD hideHUDForView:self.view animated:YES];
        // reload data here...
    });
});

詳細については、の使用法のセクションを参照してくださいMBProgressHUD

于 2012-07-10T11:03:59.587 に答える
0

何らかのメモリの問題が原因で問題が発生している可能性があります。SVProgressHUDこれを使用してみてください。これは拡張バージョンですMBProgressHUD

あなたはこのようにする必要があります:

- (void) pullAndDisplayData{

    [SVProgressHUD showWithStatus:@"Downloading..."];

    // Indeterminate mode
    ExpensesDataDownloader *downloader = [[ExpensesDataDownloader alloc] init];
    [downloader pullAndDisplayData];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([[defaults objectForKey:@"canExportCSVServer"] isEqualToString:@"1"])
    {

    }

    [self.tableView reloadData];

    // Switch to determinate mode
    HUD.mode = MBProgressHUDModeDeterminate;
    HUD.labelText = @"Updating";
    float progress = 0.0f;
    while (progress < 1.0f)
    {
        progress += 0.01f;
        HUD.progress = progress;
        usleep(15000);
    }
    // The sample image is based on the work by www.pixelpressicons.com, http://creativecommons.org/licenses/by/2.5/ca/
    // Make the customViews 37 by 37 pixels for best results (those are the bounds of the build-in progress indicators)
    HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
    HUD.mode = MBProgressHUDModeCustomView;
    HUD.labelText = @"Completed";
    sleep(2);

    [SVProgressHUD dismiss];
}

何かを割り当てたり解放したりする必要はありません。それはそのように動作します!!!

ではごきげんよう!!!

于 2012-07-10T11:01:19.007 に答える