我的应用程序具有四个View Controller(VC):

1)主页:在SKView上具有SpriteKit动画。在此VC上滑动即可使用户进入Authoring VC(下一个)。

2)创作:具有菜单(UITableView)。菜单使用户可以访问ViewGames和商店(如下)。

3)ViewGames:包含一个UICollectionView和一个带有关闭按钮的导航栏。这一次只显示一个UICollectionViewCell,并允许用户滑动以继续到下一个单元格。每个单元在SKView上都有一个SpriteKit动画,还具有三个按钮。

4)商店:拥有一个应用程序内购买商店,其UI实现为UITableView。为了便于讨论,我使用的唯一功能是SKProductsRequest取回显示在表格视图中的产品列表。

问题:在某些情况下,在ViewGames VC中,集合视图中第二个和随后的单元的UI操作非常缓慢。例如,比正常速度慢约10倍。 SKView中的动画非常慢。四个按钮(集合视图单元中的三个,导航栏中的一个)操作非常缓慢。通常,它们根本不会响应,您必须轻按几次。滑动到下一个单元格的响应类似-缓慢地(如果有的话)。 (如果我使用滑动回到第一个单元格,则第一个单元格也有类似的响应,但是最初它没有出现此问题)。

重现问题。好消息是,在我的应用程序中,重现此问题非常一致。这将产生它:


  启动应用程序>滑动以转至创作>使用菜单转至商店>
  退出商店以返回到创作>退出创作回到首页>转到
  转至创作>转到查看游戏。


其他方面:

A)如果我退出View Games,回到创作,然后重新进入View Games,这个问题是一样的。

B)应用程序的其他部分均不显示UI响应缓慢。

C)如果在View Games VC中获得此行为之后,现在我退出ViewGames并返回到Authoring,重新进入商店,再回到Authoring,然后再回到ViewGames,则问题消失了。

D)此问题仅在iOS9,iOS9.1,iOS9.2(测试版)中出现。在iOS8.4上不会发生。 (所有运行在物理设备上;我还没有尝试模拟器)。我最初使用的是Xcode 7.0.1,但是现在使用的是Xcode 7.2 beta,问题仍然存在。我的应用程序针对iOS8及更高版本。

E)如果我启动该应用程序,然后转到“创作”,然后转到“ ViewGames”,则不会发生此问题。


问题:什么会使UI的运行缓慢,但只是暂时的?


到目前为止探索的大道:

(i)我已经在“时间分析工具”中查看了此应用,但看不到任何看起来像在吸收时间的东西。

(ii)该应用程序只有一部分在进行网络交互,即商店。产品获取成功,并显示该信息。

(iii)我现在最好的猜测是,这与内存使用情况有关。当出现症状时,似乎从Authoring UICollectionView的单元格1到单元格2至少使用了一定数量的RAM(在出现问题的情况下为0.4到0.9MB;在出现问题的情况下为0.3MB没有出现)。

(iv)在该应用程序的开发历史中,当我准备向Apple提交v1.0时,我出现了内存泄漏,并表现出其中一些症状。但是,据我回忆,内存泄漏仅影响SpriteKit动画,影响所有SpriteKit动画(在Home和Authoring VC上),并且不是暂时的。您必须重新启动该应用程序才能解决该问题。

(v)我已经使用Instruments / Leaks / Allocations仔细查看了该应用程序。有一些泄漏,但似乎是来自Apple框架,而不是我的。

(vi)我已经在dealloc / deinit方法中放置了断点和日志消息,并且所有主要类似乎都在释放(例如VC,集合视图及其单元)。


更新1:11/4/15; MST:下午3:47:问题与ViewGames SpriteKit动画没有特别关系。我只是在ViewGames UICollectionViewCell中禁用了动画,问题仍然存在。滑动和按钮按下响应仍然缓慢。当然,单元仍具有SKView / SKScene。

更新2:11/4/15; MST:3:55pm:我刚刚从商店中禁用了产品获取(使用SKProductsFetch)。问题就解决了!!问题的范围缩小了!

更新3:11/4/15; MST:下午6:10:提取产品到位,但将SKProductsFetch对象的委托设置为nil,则不会发生此问题!还需要注意的是,属于我的类构造的完成处理程序(称为fetchProductsCompletion)也设置为nil。

更新4:11/4/15; MST:下午6:10:产品获取到位,并且SKProductsFetch的委托为非零,但fetchProductsCompletion设置为nil,则不会发生此问题!

最佳答案

如果要完全冻结应用程序,则可以使用sleep(amountTime)。
或使用runAfterDelay(amountTime){}进行延迟。

07-26 00:59