Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS设置需要在线程上运行_Ios_Grand Central Dispatch - Fatal编程技术网

iOS设置需要在线程上运行

iOS设置需要在线程上运行,ios,grand-central-dispatch,Ios,Grand Central Dispatch,你好 我有一个复杂的日历控件,每次选择日期项等时都需要使用setneedslayout重新绘制。我曾尝试在GCD块中运行此控件,但从未运行过。但是,当我在主线程上运行它时,setNeedsLayout运行并工作。然而,这会在我的程序中造成令人讨厌的口吃/延迟,破坏用户体验 我能知道能做什么吗?这可以在另一个线程上执行吗?我可以在另一个线程上使用NSTimer或执行选择器吗 dispatch_queue_t queue = dispatch_get_global_queue(DISPATC

你好

我有一个复杂的日历控件,每次选择日期项等时都需要使用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");
    });
});

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


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

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

1) 您两次调用重新加载日期;即使直到使用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;
    }

});
在重载日期内,仅将setNeedsLayout调用放入主队列异步块中


完成后,如果仍然存在不可接受的UI延迟级别,则需要查看正在重新绘制的视图,并查看如何使其更快。Instruments的时间分析器是查看在这些重画事件期间CPU时间使用位置的良好第一步。

是运行setNeedsLayout并导致问题的重载日期操作。目前,在主线程上运行它的上述修复当然仍然会导致延迟