在iOS中使用NSThread和autorealease池的有效方法

时间:2013-10-08 20:41:45

标签: ios uitableview nsthread nsautoreleasepool mbprogresshud

我正在我的应用程序中使用MBProgressHUD库,但有时候,当我查询大量数据时,或者在数据处理完成后立即显示进度hud甚至不显示(到那时我不再需要显示hud了。)

在另一篇文章中,我发现有时UI运行周期非常繁忙以至于无法完全刷新,所以我使用的解决方案部分解决了我的问题:现在每个请求都会提升HUD,但差不多有一半的时间应用程序崩溃。为什么?这就是我需要帮助的地方。

我有一个表视图,在委托方法didSelectRowAtIndexPath中我有这段代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    [NSThread detachNewThreadSelector:@selector(showHUD) toTarget:self withObject:nil];
    ...
}

然后,我有这个方法:

- (void)showHUD {
    @autoreleasepool {
        [HUD show:YES];
    }
}

在其他一点我只是打电话:

[HUD hide:YES];

而且,当它工作时,它可以工作,显示hud,停留然后按预期消失,有时它只会崩溃应用程序。错误:EXC_BAD_ACCESS。为什么呢?

顺便说一下,HUD对象已在viewDidLoad中分配:

- (void)viewDidLoad
{
    [super viewDidLoad];

    ...

    // Allocating HUD
    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
    [self.navigationController.view addSubview:HUD];

    HUD.labelText = @"Checking";
    HUD.detailsLabelText = @"Products";
    HUD.dimBackground = YES;
}

1 个答案:

答案 0 :(得分:0)

你需要在另一个线程上执行处理,否则处理阻止MBProgressHud绘制直到它完成,此时再次隐藏MBProgressHud。

NSThread对于卸载处理来说有点太低了。我建议使用Grand Central Dispatch或NSOperationQueue。

http://jeffreysambells.com/2013/03/01/asynchronous-operations-in-ios-with-grand-central-dispatch http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

/* Prepare the UI before the processing starts (i.e. show MBProgressHud) */

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   /* Processing here */

   dispatch_async(dispatch_get_main_queue(), ^{
      /* Update the UI here (i.e. hide MBProgressHud, etc..) */     
   });
}); 

在将处理发送到另一个线程之前,此代码段将允许您在主线程上执行任何UI工作。然后,一旦处理完成,它就会返回主线程,以允许您更新UI。