【问题标题】:Effective way to use NSThread and autorealease pools in iOS在 iOS 中使用 NSThread 和 autorealease 池的有效方法
【发布时间】:2013-10-08 20:41:44
【问题描述】:

我在我的应用程序中使用 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];

好吧,当它工作时,它会按预期显示、停留然后消失,有时它只会让应用程序崩溃。错误: 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;
}

【问题讨论】:

  • 你也在主线程上做处理吗?
  • 是的,我正在快速枚举一些数组,填充一些对象,在集合视图中显示东西......是的,我认为所有这些都是在主线程上完成的......跨度>

标签: ios uitableview nsthread nsautoreleasepool mbprogresshud


【解决方案1】:

您需要在另一个线程上执行您的处理,否则处理会阻塞 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..) */     
   });
}); 

这个 sn-p 将允许您在主线程上执行任何 UI 工作,然后再将处理分派给另一个线程。处理完成后,它会返回主线程,以允许您更新 UI。

【讨论】:

  • 但是处理是在一个委托方法中,在这种情况下是didSelectRowAtIndexPath,我怎么能在另一个线程上做这个处理呢? MBProgress Show 和 Process 都在 didSelect 中...如何将它们分开在不同的线程中?
  • 将代码 sn-p 粘贴到 didSelectRowAtIndexPath 中。我已经更新了答案,使其更清楚它是如何工作的。
  • 不,它不起作用,我的意思是,hud 出现了,除了任务完成后,一切都出现了......还有其他想法吗?
猜你喜欢
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
相关资源
最近更新 更多