【问题标题】:Xcode 7/Swift 2.1 "Message from debugger: Terminated due to memory issue"Xcode 7/Swift 2.1“来自调试器的消息:由于内存问题而终止”
【发布时间】:2015-11-28 04:19:11
【问题描述】:

我正在使用 Xcode 7 在 Swift 2.1 中开发纸牌游戏,我的应用在模拟器中运行良好,但在我的设备上测试时崩溃。

使用断点,我已将崩溃精确定位到在动画发生后运行的 NSTimer.scheduledTimerWithTimeInterval 方法(然后触发另一个动画)。

我想这可能是我的图像的大小,因为有些非常大 (>4 MB),所以我压缩了动画中的所有图像,现在它们总共占用不到 1 MB。

我还运行了 Zombie 和 Leak 工具,但一无所获,所以我有点困惑。这是它崩溃的代码。

func animateOnDeal() {
    self.playerAnimatedCard.hidden = false
    self.dealerAnimatedCard.hidden = true
    cardOneToDeal()
}

func cardOneToDeal() {
    UIView.animateWithDuration(0.5, animations: {
        self.playerAnimatedCard.center.x -= self.view.bounds.width
        }, completion: {finished in self.flipCardOne()})
}

func flipCardOne() {
    self.playerAnimatedCard.playFlipAnimation()
    NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "cardTwoToDeal", userInfo: nil, repeats: false)
}

下面是实际运行动画的代码(在 UIImageView 子类中):

func playFlipAnimation() {
    self.image = UIImage(named: "cardback2.png")
    self.animationImages = nil
    var imgArray = [UIImage]()

    for var x = 1; x <= 12; x++ {
        let img = UIImage(named: "img\(x).png")
        imgArray.append(img!)
    }

    self.animationImages = imgArray
    self.animationDuration = 0.3
    self.animationRepeatCount = 1
    self.startAnimating()

作为旁注,调试器只是声明:“来自调试器的消息:由于内存问题而终止。”

任何帮助将不胜感激,如果您需要更多信息,请告诉我。谢谢!

编辑:

因此,为了进行更多测试,我将 func playFlipAnimation 更改为迭代并添加 5 个图像而不是原来的 12 个。这似乎已经解决了崩溃问题,但我仍然不确定为什么有更多图像是首先使应用程序崩溃。

【问题讨论】:

  • 由于内存问题而被终止并不一定表示存在泄漏。如果您还没有这样做,我建议您使用分配工具进行一些分析,以准确了解您的内存增长发生在哪里。在设备上运行您的应用程序时,请务必勾选“记录引用计数”并记下持久对象的数量。网上有许多关于分配工具的教程,但如果您需要更多指导,请在此处告诉我。
  • @DerekLee,感谢您的建议!所以我运行了 Allocations 工具并收到了几个标题为“一个 Objective-C 消息被发送到地址:0x7fc5dda8bbf0 的无效 'IDEActivityReport' 对象”的标志。我尝试搜索此消息,但没有找到任何实质性内容。知道是什么原因造成的吗?
  • @DerekLee 因此,为了进行更多测试,我将 func playFlipAnimation 更改为迭代并添加 5 个图像而不是原来的 12 个。这似乎解决了崩溃,但我仍然不确定至于为什么拥有更多图像首先会使应用程序崩溃。
  • 图像可能是非常占用内存的对象,您如何加载图像、图像有多大以及您是否占用内存都在这里发挥了重要作用。从分配工具中,您应该能够查看您正在加载的图像是否被保留(持久对象的数量没有下降),以及您正在以比您显示的分辨率更大的分辨率加载图像可以减小尺寸。还没有听说过“IDEActivityReport”,所以很抱歉我无法具体提供帮助,但对象使用和图像优化可能是一个不错的起点。
  • 这不是您问题的答案,但它是一个可能有帮助的建议。如果您的计算机上有空间,您应该下载 XCode 8 beta,因为它有一个非常酷的功能,可以显示导致内存过载的地图。他们在 developer.apple.com 上有一段来自 WWDC 会谈的视频。也许检查一下?希望你能找到答案!

标签: ios xcode swift swift2 swift2.1


【解决方案1】:

几点:

  1. 正如 Derek Lee 已经指出的那样,图像可能会占用大量内存。以我的经验,运行时还将在使用后将图像缓存在后台一段时间。这可能与您的情况有关,因为查看您的代码,每次调用动画时,您都会加载一组新的十二张图像。如果您多次迭代该动画,那么这将很快增加大量内存,尤其是对于 1MB 的图像文件。在这种情况下,虽然它在短期内可能看起来效率低下,但您可能需要考虑在初始化类时初始化一个图像数组,您可以重复使用它。

  2. 在迭代循环时可以做的一件事就是将它放在一个自动释放池中。请参阅开发人员参考:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html 我知道从技术上讲,ARC 应该是现代 iOS 世界中你所需要的一切,但当我在我的一个应用程序中构建一个数据密集型程序时,这对我很有用。

  3. 您不太可能触发在模拟器中运行的内存警告,因为没有考虑到底层硬件的可用容量比目标设备大得多。在我无限的智慧中,我曾经让一些东西运行,最终使用了 50GB 的内存,但这并没有在模拟器上触发任何类型的警告!

  4. 顺便说一句,我认为您应该能够将卡片图像压缩到远小于 1 MB。当然,这取决于您要使用哪种图像(它们是照片吗?),但如果它是一个简单的 .png,那么对我来说这似乎很大。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,发现是我在方案中勾选了Enable Zombie Objects的问题。所以你也可以检查一下。

    【讨论】:

    • 我也做了同样的事情......但在 Sqlite db 存储 15 张图像后仍然面临问题。
    猜你喜欢
    • 2018-09-28
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 2018-03-12
    相关资源
    最近更新 更多