代码之家  ›  专栏  ›  技术社区  ›  Matt

一个表视图加载另一个表视图时的活动指示器

  •  1
  • Matt  · 技术社区  · 15 年前

    我花了大约一天时间试图让一个表单元格在加载新视图时显示一个活动指示器。在didselectrowatindexpath上,我希望在以下运行时显示指示器

    [self.navigationController pushViewController:subKeywordController animated:YES];
    

    然后,此控制器运行相当密集的SQL查询

    我在网上搜索并阅读了几十篇文章,但似乎没有一篇能帮助解决我的具体问题。我知道我需要在另一个线程中运行指示器,因为推送和随后的加载优先,但我不确定如何执行。我以前曾想过在控制器中运行SQL查询,但这变得非常混乱。

    奇怪的是我一直在使用 MBProgressHUD 在同一个表视图中显示忙碌的光标,没有问题。只有当我应用搜索,然后选择导致此错误的结果之一时:

    bool _webtrythreadlock(bool),0x1D79b0:试图从非主线程或Web线程的线程获取Web锁。这可能是从辅助线程调用uikit的结果。现在崩溃了…

    该应用程序在iPhone上继续运行,但会使模拟器崩溃。

    任何帮助都将不胜感激。

    1 回复  |  直到 15 年前
        1
  •  2
  •   deanWombourne    15 年前

    问题是控制器中的任务正在保存UI代码(但您可能已经知道!)。解决这一问题的一个简单而廉价的方法是使用计时器在启动慢速任务(在本例中是SQL查询)时稍微延迟一点:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // instead of running the SQL here, run it in a little bit
        [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doSQL:) userInfo:nil repeats:NO];
    
        // Show the please wait stuff
        [activityIndicator setHidden:NO];
    }
    
    - (void)doSQL:(NSTimer *)timer {
        // Do your sql here
    }
    

    解决此问题的另一种方法是将SQL移动到单独的线程中:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // instead of running the SQL here, run it in a little bit
        [self performSelectorInBackground:@selector(doSQL) withObject:nil];
    
        // Show the please wait stuff
        [activityIndicator setHidden:NO];
    }
    
    - (void)doSQL {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
        // Do your sql here
    
        // Tell the main thread
        [self performSelectorOnMainThread:@selector(doneSQL) userInfo:nil waitUntilDone:YES];
    
        // Cleanup
        [pool release];
    }
    
    - (void)doneSQL {
        // Update your UI here
    }
    

    希望有帮助!