Objective-C: 为什么我的应用程序不执行任何动画,并且在我偶尔打开我的应用程序时做一些奇怪的意外事情?

Objective-C: Why does my app not perform any animations and do wonky unexpected things when I open up my app occasionally?

所以这很难解释,但是......有时当我打开我的应用程序时,它只是忽略所有动画并执行 "animation block" 而不是动画,所以它会立即为每个贯穿整个应用程序的动画。我对为什么会发生这种情况感到困惑,因为其他时候当我打开该应用程序时,它运行得非常好,但有时当我打开该应用程序时它只是在我面前爆炸并忽略所有动画。

当我添加这行代码时问题开始了:

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

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

这行代码:

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

保证以不可预测的方式"explode"。

引用 performSelectorInBackground: 的文档:

creates a new thread in your application, putting your application into multithreaded mode if it was not already. The method represented by aSelector must set up the thread environment just as you would for any other new thread in your program.

reloadData 方法没有 "setup the thread environment",因此如果你执行它会搞砸。

此外,引用 reloadData 的文档:

Marks the table view as needing redisplay, so it will reload the data for visible cells and draw the new values.

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

这部分特别糟糕,因为根据其他线程中发生的情况,从后台线程中绘制通常会工作但通常它不会工作而且你'您会确切地看到您所描述的问题类型。

因此,要修复您的代码,请更改这行代码:

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

为此:

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

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