【问题标题】:ActivityIndicator doesn't stop after computationsActivityIndi​​cator 在计算后不会停止
【发布时间】:2013-02-05 08:04:33
【问题描述】:

我正在尝试在上传文件时制作活动指示器,所以我找到了很多解决方案,但我想我并不完全理解它们,所以我的代码如下所示:

- (void) startSpinner {

UIActivityIndicatorView  *spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner setCenter:CGPointMake(self.view.frame.size.width/2.0, self.view.frame.size.height/2.0)];
[self.view addSubview:spinner];
[spinner startAnimating];

}


- (void)startSync {

[NSThread detachNewThreadSelector:@selector(startSpinner) toTarget:self withObject:nil];

// computations 

[self.spinner stopAnimating];
} 

所以在我执行 [self startSync] activityIndi​​cator 后出现,但上传后它并没有停止。此外,如果我在其他地方(不在 (void)startSpinner 中)声明活动指示器,例如在 viewDidLoad 中,并且只执行 [self startAnimating] 它根本不会出现。请帮我找出错误。

【问题讨论】:

    标签: ios objective-c cocoa-touch uiactivityindicatorview


    【解决方案1】:

    您在不是主线程的线程上执行 UI 操作。 您永远不应该使用执行 UI 相关任务的选择器调用 detachNewThreadSelector

    一个更好、更容易理解的方法是:

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.activityIndicator startAnimating];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //Perform lengthy operations
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.activityIndicator stopAnimating];
            });
        });
    });
    

    此外,如果您选择使用选择器 - 请确保您的 UIActivityIndi​​catorView 在方法范围之外声明。

    【讨论】:

    • 您说“.. 永远不应该使用执行 UI 相关任务的选择器调用 detachNewThreadSelector。”但是您使用 dispatch_get_main_queue()。他们不一样吗?
    • 否 - detachNewThreadSelector 创建一个在后台运行任务的线程。使用 GCD 的 dispatch_get_main_queue 确保代码在主线程上运行。
    • 我试过你的代码,结果和我之前的一样,但是现在主线程没有被阻塞,所以活动指示器不会消失
    • 尝试将activityIndi​​cator的 hidesWhenStopped 属性设置为YES
    • 您可以尝试将 DISPATCH_QUEUE_PRIORITY_DEFAULT 更改为 DISPATCH_QUEUE_PRIORITY_HIGH。另外,请确保您对活动指示器的引用是有效的(不是零)。
    【解决方案2】:
    - (void) startSpinner
    {
        self.spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        [spinner setCenter:CGPointMake(self.view.frame.size.width/2.0, self.view.frame.size.height/2.0)];
        [self.view addSubview:spinner];
        [spinner startAnimating];
    }
    
    
    - (void)startSync
    {
        [NSThread detachNewThreadSelector:@selector(startSpinner) toTarget:self withObject:nil];
    
        // computations 
    
        [self.spinner performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
        self.spinner = nil;
    } 
    

    【讨论】:

      【解决方案3】:

      你在 startSpinner 方法中声明了局部变量 spinner。

      当你调用 self.spinner 时,它不会影响你在 startSpinner 方法中声明的局部变量 spinner。您有 2 个具有相同名称的单独变量。

      你必须声明

      spinner = [[UIActivityIndi​​catorView alloc]initWithActivityIndi​​catorStyle:UIActivityIndi​​catorViewStyleGray];

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多