MBProgressHUD崩溃应用程序重新加载tableView上的数据

时间:2012-07-10 10:47:54

标签: iphone objective-c ios uitableview mbprogresshud

当我从网络服务下载数据时,我正在使用这段代码在我的一个视图的顶部显示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);
}

非常感谢任何帮助。

杰克

3 个答案:

答案 0 :(得分:2)

pullAndDisplayData方法在单独的线程上运行。这样MBProgressHUD可以使用UI线程来显示自己。您应该始终从主(UI)线程更新UI。使用performSelectorOnMainThread:方法调用[self.tableView reloadData];和其他UI内容。我假设[downloader pullAndDisplayData];是同步调用。

答案 1 :(得分:1)

来自MBprogressHUD API

/** 
 * 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的{​​{3}}。

答案 2 :(得分: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];
}

无需分配或发布任何内容。它就像那样工作!!!

一切顺利!!!