gpt4 book ai didi

objective-c - UI动画和主runloop之间有什么关系

转载 作者:行者123 更新时间:2023-12-03 17:21:51 26 4
gpt4 key购买 nike

我有这段代码等待加载任务,显示 ActivityIndi​​cator View

  if (isLoading) {
self.tipView = [[BBTipsView alloc] initWithMessage:@"loading..." showLoading:YES parentView:self.view autoClose:NO];
self.tipView.needsMask = YES;
[self.tipView show];
while (isLoading) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
[self.tipView close];
}

加载 View 将呈现动画,直到 isLoading 变为 false。这是我的问题:在主线程中运行运行循环将阻塞主线程,直到有源事件到来或计时器触发。但为什么加载 View 保持动画而主运行循环没有返回?

-----由bupo编辑----

我发现当计时器触发时,运行循环不会返回。这将有意义,动画刷新 ui 由 CADisplayLink 计时器触发。

Note that from the perspective of NSRunloop, NSTimer objects are not "input"—they are a special type, and one of the things that means is that they do not cause the run loop to return when they fire.

最佳答案

NSRunLoop 方法 runMode:beforeDate: 运行直到给定日期或直到找到要处理的单个事件 - 之后调用返回。您在主运行循环上调用它([NSRunLook currentRunLoop])。因此,即使您认为您正在阻塞主运行循环,但您并没有 - 您正在导致事件得到服务。因此,即使您可能认为自己“阻止”了主运行循环,动画计时器也可以运行。

要确认这一点,请注释掉对 runMode:beforeDate: 的调用,您应该会看到 UI 卡住,直到操作完成。

编辑:查看 CodaFi 对您问题的评论。如果您出于兴趣注释掉对 runMode:beforeDate: 的调用,实际上会发生什么?

原始答案:

不建议使用这种代码风格来启动和停止 UI 动画。 除非必要,否则不要乱搞运行循环。并且有一个紧密的循环来检查从其他地方更改的 bool 标志通常是一种代码味道,这意味着有更好的方法。

相反,异步执行并且不坐在主线程上:

   // on main thread
self.tipView = [[BBTipsView alloc] initWithMessage:@"loading..." showLoading:YES parentView:self.view autoClose:NO];
self.tipView.needsMask = YES;
[self.tipView show];
} // end of the method

- (void)loadingHasFinished {
// assuming this method called on main thread
[self.tipView close];
}

显然,您必须确保适本地调用 loadingHasFinished

如果在后台线程而不是主线程上调用 loadingHasFinished,您将需要如下所示的内容:

- (void)loadingHasFinished {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tipView close];
});
};

关于objective-c - UI动画和主runloop之间有什么关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23013072/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com