当我从网络服务下载数据时,我正在使用这段代码在我的一个视图的顶部显示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);
}
非常感谢任何帮助。
杰克
答案 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];
}
无需分配或发布任何内容。它就像那样工作!!!
一切顺利!!!