0

再会,

我有一个复杂的日历控件,每次我选择日期项目等时都需要使用 setneedslayout 重新绘制。我尝试在 GCD 块中运行它,但它从未运行过。但是,当我在主线程上运行它时 setNeedsLayout 运行并工作。但是,这会导致我的程序出现令人讨厌的卡顿/延迟,从而破坏用户体验。

我能知道可以做什么吗?这可以在另一个线程上执行吗?我可以使用 NSTimer 或在另一个线程上执行选择器吗?

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        //[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    });
    @try {
        NSLog(@"New Thread");

        if (self.selectedDate) {
            [datesToReload addObject:self.selectedDate];
        }
        if (date) {
            [datesToReload addObject:date];
        }
        self.selectedDate = date;
        [self reloadDates:datesToReload];

        [self performSelectorOnMainThread:@selector(reloadDates:) withObject:datesToReload waitUntilDone:NO];
        //[self perform]

        if (visible && date) {
            self.monthShowing = date;
        }
    }
    @catch (NSException *exception) {
        NSLog(@"Exception = %@", exception);
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        //[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
        NSLog(@"Main Thread");
    });
});
4

2 回答 2

0

建议,使用上面的代码示例:

1)你调用 reloadDates 两次;即使视图在使用 perform_selector 的第二次调用之前没有成功更新,您仍然会执行两次相同的工作。仅此一项就会使您在 reloadData 方法中遇到的任何 UI 延迟加倍。

2)对大部分工作使用较低优先级的队列:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

    if (self.selectedDate) {
        [datesToReload addObject:self.selectedDate];
    }

    if (date) {
        [datesToReload addObject:date];
    }

    self.selectedDate = date;
    [self reloadDates:datesToReload];

    if (visible && date) {
        self.monthShowing = date;
    }

});

在 reloadDates 中,将 setNeedsLayout 调用放在主队列异步块中。

完成后,如果您的 UI 延迟仍然无法接受,您需要查看正在重绘的视图并了解如何使其更快。Instruments 的 Time Profiler 是了解在这些重绘事件期间您在何处使用 CPU 时间的良好第一步。

于 2013-05-24T20:26:55.923 回答
0

所有 UI 更新都需要在主线程上运行,您不能从后台线程更改 UI(它会产生不可预知的副作用)。

如果您遇到性能问题,您应该使用Instruments分析您的应用程序来找出处理时间的原因并解决该问题(例如,您真的需要重新加载所有日期以及它需要大量时间吗?)。

于 2013-05-21T06:04:38.617 回答