我应该在主线程上启动和停止UIActivityIndi​​cator实例吗?

时间:2014-07-12 15:00:47

标签: ios objective-c cocoa-touch grand-central-dispatch uiactivityindicatorview

示例:

[query findObjectsInBackgroundWithBlock:^(NSArray *favObjects, NSError *error) {
    for (PFObject *favObject in favObjects) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [cell setSizeLabel:[_arrayOfSizes objectAtIndex:[[favObject valueForKey:@"size"] integerValue]]];
            [[cell sizeDropDownButton] setTitle:[cell sizeLabel] forState:UIControlStateNormal];
        });

        if ([[[cell currentObject] valueForKey:@"alternativeColour"] boolValue]) {

            // Colours are stored in db on parse as numbers, I use array below to determine which colour is being red back by valueForkey below

            dispatch_async(dispatch_get_main_queue(), ^{
                [cell setColourLabel:[_arrayOfColours objectAtIndex:[[favObject valueForKey:@"colour"] integerValue]]];
                [[cell colourDropDownButton] setTitle:[cell colourLabel] forState:UIControlStateNormal];
            });
        }

        [[cell priceLabelSpinner] stopAnimating];
        [[cell titleLabelSpinner] stopAnimating];
        [[cell sizeDropDownButton] setHidden:NO];
        [[cell colourDropDownButton] setHidden:NO];

    }

}];

您可以看到我在主队列上设置按钮标签标题。但是下面我停止了后台队列上的旋转以及取消隐藏按钮。这是对的吗?

3 个答案:

答案 0 :(得分:3)

应该从主线程调用任何可能导致您查看更改的内容:

  

必须对应用程序的用户界面进行操作   主线程。因此,您应该始终调用UIView的方法   来自应用程序主线程中运行的代码的类。该   只有在创建视图时,这可能不是绝对必要的时间   对象本身,但所有其他操作应该发生在主要   线程。

因此,考虑到Apple的建议,您应该将代码重写为:

[query findObjectsInBackgroundWithBlock:^(NSArray *favObjects, NSError *error) {
    for (PFObject *favObject in favObjects) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [cell setSizeLabel:[_arrayOfSizes objectAtIndex:[[favObject valueForKey:@"size"] integerValue]]];
            [[cell sizeDropDownButton] setTitle:[cell sizeLabel] forState:UIControlStateNormal];
        });

        if ([[[cell currentObject] valueForKey:@"alternativeColour"] boolValue]) {

            // Colours are stored in db on parse as numbers, I use array below to determine which colour is being red back by valueForkey below

            dispatch_async(dispatch_get_main_queue(), ^{
                [cell setColourLabel:[_arrayOfColours objectAtIndex:[[favObject valueForKey:@"colour"] integerValue]]];
                [[cell colourDropDownButton] setTitle:[cell colourLabel] forState:UIControlStateNormal];
            });
        }

        dispatch_async(dispatch_get_main_queue(), ^{
            [[cell priceLabelSpinner] stopAnimating];
            [[cell titleLabelSpinner] stopAnimating];
            [[cell sizeDropDownButton] setHidden:NO];
            [[cell colourDropDownButton] setHidden:NO];
        });

    }

}];

答案 1 :(得分:2)

停止动画或隐藏视图也是UI操作,因此它们也必须在主线程上完成。

答案 2 :(得分:0)

根据Apple Documentation,所有UI更新都应在主线程中进行。因此,修改了您的代码并在单个UI块中包含所有dispatch_async更新,请尝试以下操作: -

[query findObjectsInBackgroundWithBlock:^(NSArray *favObjects, NSError *error) {
    for (PFObject *favObject in favObjects) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [cell setSizeLabel:[_arrayOfSizes objectAtIndex:[[favObject valueForKey:@"size"] integerValue]]];
            [[cell sizeDropDownButton] setTitle:[cell sizeLabel] forState:UIControlStateNormal];
    if ([[[cell currentObject] valueForKey:@"alternativeColour"] boolValue]) {

        // Colours are stored in db on parse as numbers, I use array below to determine which colour is being red back by valueForkey below
            [cell setColourLabel:[_arrayOfColours objectAtIndex:[[favObject valueForKey:@"colour"] integerValue]]];
            [[cell colourDropDownButton] setTitle:[cell colourLabel] forState:UIControlStateNormal];

    }

    [[cell priceLabelSpinner] stopAnimating];
    [[cell titleLabelSpinner] stopAnimating];
    [[cell sizeDropDownButton] setHidden:NO];
    [[cell colourDropDownButton] setHidden:NO];

}

}];