Objective-C:当我偶尔打开我的应用程序时,为什么我的应用程序不执行任何动画并且做了不可思议的事情?

时间:2015-08-18 03:55:49

标签: ios animation core-animation

所以这很难解释,但是...有时当我打开我的应用程序时,它会忽略所有动画并执行"动画块"没有它是一个动画,所以它通过整个应用程序立即为每个动画做到这一点。我很困惑为什么会发生这种情况,因为其他时候我打开应用程序时,它的效果非常好,但偶尔当我打开应用程序时,它只会在我的脸上爆炸并忽略所有动画。

当我添加这行代码时问题就出现了:

[weakSelf.tableView performSelectorInBackground:@selector(reloadData) withObject:nil];

有人可以帮忙解释为什么会这样吗?

1 个答案:

答案 0 :(得分:3)

这行代码:

[weakSelf.tableView performSelectorInBackground:@selector(reloadData) withObject:nil];

保证以不可预测的方式“爆炸”。

引用performSelectorInBackground:的文档:

  

在您的应用程序中创建一个新线程,如果尚未将您的应用程序置于多线程模式。 aSelector表示的方法必须像设置程序中的任何其他新线程一样设置线程环境

reloadData方法不会“设置线程环境”,因此如果执行它会严重搞砸。

另外,引用reloadData的文档:

  

将表格视图标记为需要重新显示,因此它会重新加载可见单元格的数据, 绘制新值

注意我以粗体突出显示的部分。绘制到屏幕必须在主线程上发生,否则一切都会搞砸。背景线程上的屏幕绘图是不可靠的,不应该这样做。

这一部分特别糟糕,因为根据其他线程中发生的事情,从后台线程中抽取通常会起作用但通常它不起作用,你会看到确切的那种你所描述的问题。

因此,要修复代码,请更改以下代码行:

[weakSelf.tableView performSelectorInBackground:@selector(reloadData) withObject:nil];

对此:

dispatch_async(dispatch_get_main_queue(), ^(void){
  [weakSelf.tableView reloadData];
});

这样reloadData操作将在主线程(也称为队列)上执行,一切都应该是好的。