SpriteKit场景切换时的内存问题

2024-01-03

Ok so awhile back in testing I had a random crash with no error, and I have no clue why. So i went into analyze things and I came up with the following data. Data

看来我的内存使用量越来越高,直到达到稳定状态。请注意,一般曲率的斜率在开始时如何大于后来的斜率。 (您可能会注意到这是我第一次进入并分析此类事情)。

现在游戏中发生的情况是基本上有两个屏幕。 1. 菜单:这个屏幕有很多纹理,但除了有玩游戏的按钮外什么也不做 2. 游戏:这有太多的纹理,并且占用大量 CPU,因为它是实际的游戏。 3.死亡:这个屏幕有一个资产,它是一个允许你重玩游戏的按钮。这不应该使用太多内存或CPU。但它仍然有记忆。对我来说,这尖叫着无论“内存泄漏”是什么,都正在发生。

如果你看一下图表,基本上游戏中发生的事情是菜单启动,第一个峰值是加载实际游戏,然后我就死了。从那时起,我就在游戏和死亡屏幕之间切换,每个尖峰都表明游戏场景正在加载。

如果这些数据是我预测的方式,那么您会发现死亡屏幕的非常小的内存使用量与返回到游戏内存使用量之间存在振荡。

这个故事的寓意是,我非常确定精灵套件在切换场景后没有正确清理,如果可能的话,我需要知道原因。

顺便说一句,为了切换场景我正在使用 maxkargin 详细制作的方法here https://stackoverflow.com/questions/32003930/how-to-create-another-screen-on-my-app/32008866#32008866

顺便说一句,我正在快速使用精灵套件、SKScenes 和 SKSpriteNodes

非常感谢!


造成这种情况的原因有几个,我的游戏也遇到了类似的问题。如果操作正确,则无需删除纹理等内容。删除每个场景更改上的纹理也不理想,您希望将它们保留在内存中以提高性能,这样就不必每次都重新加载。

这是一个基本检查表,您可以使用它来查看是否造成内存泄漏。

1)将带有 print 语句的 deinit 方法添加到每个场景/类。如果 deinit 被调用,则您的场景已正确解除分配。

 deinit {
    print("Deinit GameScene")
  }

2)您是否通过在两个类之间创建引用来在某处创建强引用循环?

Apple 强引用循环的经典示例

 class Person {
    var dog: Dog?
  }

 class Dog {
   var person: Person?
 }

要修复它,您必须使这 2 个属性中的 1 个变弱

  class Person {
     var dog: Dog?
  }

  class Dog {
     weak var person: Person?
  }

选项的良好实践是当不再需要它们时将它们设置为零。

 person = nil

也许查看 google 和 Apple Swift 文档以了解如何处理此问题。前段时间我也问过类似的问题

Swift SpriteKit ARC 傻瓜版 https://stackoverflow.com/questions/35798496/swift-spritekit-arc-for-dummies

3)你使用闭包吗?它们可能会导致内存泄漏。

SpriteKit 中更常见的场景是这两个示例,它们可能/将导致内存泄漏并使场景无法释放。 (动作 2 是捕获 self 的闭包)

 // Example 1
 let action1 = SKAction.wait(forDuration: 1)
 let action2 = SKAction.run(someMethod)
 let sequence = SKAction.sequence([action1, action2])
 run(SKAction.repeatForever(sequence))

 // Example 2
 let action1 = SKAction.wait(forDuration: 1)
 let action2 = SKAction.run {
      self.someMethod()
 }
 let sequence = SKAction.sequence([action1, action2])
 run(SKAction.repeatForever(sequence))

一个好的经验法则是,当编译器强制您使用 self 时,您很可能会在不使用weak/unowned 的情况下造成内存泄漏。

因此,要修复上述 2 个 SKAction 示例,您可以确保在更改场景时始终删除所有操作,或者在我看来,最好将代码更改为此,以避免首先产生内存泄漏。

 let action1 = SKAction.wait(forDuration: 1)
 let action2 = SKAction.run { [weak self] in
      self?.someClassMethod()
  }
 let sequence = SKAction.sequence([action1, action2])
 run(SKAction.repeatForever(sequence))

请注意,在上面的所有示例中,您也可以编写

 .... { [unowned self] in

比你不需要使用 ?在闭包中

 self.someMethod()

当你使用 unowned 时,你基本上说 self 永远不会为零,如果调用闭包时它实际上是 nil ,则可能会导致崩溃。如果您使用weak self,您会告诉编译器在调用闭包之前self可能会变成nil,因此self是避免崩溃的可选选项。

我认为使用“弱”而不是“无主”来避免这种情况几乎总是更好。在我的一款游戏中,我在从 iTunes 获取 StoreKit 产品时调用的闭包中使用了 unowned self。这导致我发生了微妙的崩溃,因为我可以在调用闭包之前退出 SKScene。如果你使用弱自我,你不会崩溃,因为你使用了选项。

希望这个对你有帮助

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpriteKit场景切换时的内存问题 的相关文章

  • Cocoa webview UserAgent“webkit-legacy”问题

    我解决了这个问题 请看下面所选的答案 我一直在努力寻找导致 OSX Cocoa 应用程序的 WebView 与 Safari 表现不同的原因 事实证明 用户代理是不同的 有点明显 并且我正在访问的网站不知道如何处理它 令人惊讶的是 它是ht
  • if let 不解开 MKAnnotation 的 title 属性的可选值

    我想用 if let 语句解开可选值 我需要获得 MKAnnotation 的标题 func mapView mapView MKMapView didSelect view MKAnnotationView if let title vi
  • iOS WebView 空白

    我已使用 YouTube 的标准嵌入网址在我的 iOS 8 3 应用程序中嵌入了 YouTube 视频 sample http www youtube com embed HkAK9QRe4ds 它按预期工作 但看起来很奇怪 那个白色间隙
  • iOS 联系人 如何通过电话号码获取联系人

    我只想通过电话号码获取联系人姓名 我尝试过这个 但速度太慢 CPU 速度超过 120 let contactStore CNContactStore let keys CNContactGivenNameKey CNContactFamil
  • 如何在应用程序打开或关闭的情况下在后台的特定日期时间快速运行任务

    我正在开发闹钟应用程序 我需要在特定时间安排闹钟 我使用scheduleLocalNotification用于安排警报 它工作正常 如我所愿 BUT在触发警报之前 我需要向 API 服务器发出请求 在该请求中 我想检查从 API 服务器返回
  • 如何在 RealityKit 中录制视频?

    我在 Xcode 中有一个 RealityKit 项目 我想记录ARView 我考虑过ReplayKit 但那是为了屏幕录制 我只想录制ARView与它的相机饲料 我考虑过 AFathi 的开源项目 ARVideoKit 但它不支持 Rea
  • 在 Swift 中使用 NSCoding 归档可选结构数组?

    我已经在 Obj C 中完成了大量 NSCoding 归档 但我不确定它如何处理 Swift 中的结构 也不确定它如何处理具有可选值的数组 这是我的代码 public struct SquareCoords var x Int y Int
  • 如何使用 AVCaptureVideoPreviewLayer 从相机应用程序实现 2 倍变焦

    我的应用程序中有一个 AVCaptureVideoPreviewLaye 它运行良好 并且显示与相机应用程序相同的预览视频 我想实现相机应用程序的 2 倍变焦功能 我该怎么做呢 基本上 我希望我的预览层将视频源更改为与您在点击 1x 图标将
  • 查询链接到 GeoFire 的 firebase 数据

    读完这些问题后 将 Geofire 位置与 Firebase 条目关联 https stackoverflow com questions 33885733 associate geofire location with firebase
  • 如何使用 Swift 将文本复制到剪贴板/粘贴板

    我正在寻找一个干净的示例 说明如何将文本复制到 iOS 剪贴板 然后可以在其他应用程序中使用 粘贴 该功能的好处是可以快速复制文本 无需传统文本复制的标准文本突出显示功能 我假设关键课程位于UIPasteboard 但在中找不到相关区域他们
  • 当我关闭应用程序时,我收到来自调试器的消息:由于信号 15 而终止

    我该如何解决这个问题 我不知道它是否影响了我在此链接中的问题我之前关于核心数据的问题 https stackoverflow com questions 30012086 swift core data does not store the
  • Xcode 8:使用 iOS 9.3 基础 SDK 编译?

    我在 Xcode 8 0 beta 8S128d 中将 iOS 应用程序升级到 Swift 3 0 我以为一切都已准备就绪 并将其上传到 iTunes Connect 当我点击 提交审核 时 它给了我一个包含 26 个错误的列表 每个嵌入式
  • 用eclipse测试java程序的内存消耗[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • supportedInterfaceOrientations 方法不会重写其超类中的任何方法

    在 UIViewController 中 这段代码 public override func supportedInterfaceOrientations gt UIInterfaceOrientationMask if let mainC
  • Swift Siesta 访问响应原始数据

    我的 API 中有一个返回 PDF 文件内容的方法 如何在成功回调中获取响应的原始数据 所有午睡响应均以原始数据开始 以基础类型的形式Data 然后运行变压器管道 http bustoutsolutions github io siesta
  • 在 macOS 上使用 Swift 3 从剪贴板读取

    我是 Swift 的初学者 我想弄清楚如何在 macOS Swift 3 上读取已复制到剪贴板的内容 我搜索了很多 但似乎找不到任何有效的东西 我从网上尝试过的一些事情 var pasteboardItems NSPasteboardIte
  • 上下文菜单未在 SwiftUI 中更新

    我正在尝试设置 SwiftUI contextMenu带有一个切换按钮Bool价值 上下文菜单的按钮文本应该在以下情况下更改 Bool切换 但上下文菜单不会更新 有没有办法强制更新上下文菜单 描述问题的示例代码 import SwiftUI
  • Swift 中计算只读属性与函数

    在 Swift WWDC 简介会话中 只读属性description被证明 class Vehicle var numberOfWheels 0 var description String return numberOfWheels wh
  • Swift - 保存在 TableView 中选择的复选标记

    我对 Swift 相当陌生 并且在 TableView 多重选择方面遇到问题 我有多个选择 可以用复选标记进行检查 类似于待办事项列表 当我检查项目时 我希望能够返回 ListView 并保存我的选择 我假设将其保持在已保存状态的代码将位于
  • TestFlight 安装的应用程序因 Swift 包管理器依赖项而崩溃

    我们已经迁移了一些 CocoaPod 依赖项 以便在 Xcode 11 中使用 Swift Package Manager 进行构建和链接 但是 每当我们将应用程序提交到 AppStore Connect 并使用 TestFlight 进行

随机推荐

  • 在 Word 中引用 Excel 单元格

    有谁知道用于直接在 Word 文档中引用 Excel 单元格的预打包解决方案 例如 TestExcel Tab1 A1 亲爱的 TestExcel Tab1 A2 先生 我们的系统已提醒我们您的帐户 TestExcel Tab1 Accou
  • 使用 simctl 运行 XCTest 包

    我有一个 XCTest 包 我可以使用它在模拟器上通过 xcode 运行simctl 我使用的是 iPhone 6 iOS 9 1 模拟器 环境变量如下 export SIMCTL CHILD TestBundleLocation User
  • Knockout - 被点击的元素

    我有以下标记 fieldset div div fieldset
  • 如何将两个整数相除以获得双精度数?

    如何将两个整数相除以获得双精度数 您想要投射数字 double num3 double num1 double num2 注意 如果 C 中的任何参数是double a double使用除法 结果是double 因此 以下内容也可以工作 d
  • Python将变量视为文字/原始字符串[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我不敢相信治疗如此困难variable as a 原始字符串 我搜索并发现了类似的问题 但没有正确的答案 我有一个带有存储域名的变量 do
  • GMA 500 集成显卡上的 WPF 性能缓慢

    我的团队正在开发要部署在 Intel Atom Z530 上网本硬件平台上的 WPF 应用程序 Intel Atom Z530 配备 Intel GMA 500 集成显卡 具有 PowerVR SGX 535 GPU 核心 PowerVR
  • 射线与平面的交点坐标

    我有一条射线和一架飞机 射线与平面相交 我想知道在哪里 如何获得该交点的世界坐标 我的特殊情况是 我将屏幕坐标取消投影到相机并创建光线 该平面是场景的地面 var vector new THREE Vector3 mousePosition
  • 如何在不刷新整个页面的情况下让 Grunt/Watch/LiveReload 重新加载 Sass/CSS?

    到目前为止 我已经让一切按照我想要的方式工作 即监视我想要的所有文件并在发生更改时刷新 除了我希望能够对 Sass CSS 进行修改并刷新它在没有页面加载的浏览器中 这不是什么大问题 但有时我会在进行一些页面交互后尝试修改某些内容的样式 并
  • 使用“data.table”根据变量获取子组的第一个

    考虑一个由分组变量组成的数据集 这里id 和一个有序变量 这里date df lt data frame id rep 1 2 2 date 4 1 id date 1 1 4 2 2 3 3 1 2 4 2 1 我想知道最简单的方法是什么
  • iPhone Web App - 在 iOS8 中停止身体弹跳/滚动

    是的 我知道 这个问题之前已经被问过一千次了 感谢你们所有人 我终于找到了一个解决方案 最终在 更新到 iOS 8 后 似乎没有任何效果 iOS7 中最适合我的是什么 Css html body scrollable overflow au
  • mysql中选择部分表列数据

    我有一个包含 2000 个条目的 照片 表 该表有一列名为photo note其中包含以下格式但具有不同放大值的数据 Magnification 30x The resolution varies depending on 我需要选择以 分
  • CTE(通用表表达式)与临时表或表变量,哪个更快?

    CTE 通用表表达式 与Temp tables or Table variables 哪个更快 正如我在评论中已经说过的 这取决于 它确实取决于您的查询 您的数据 有多少 它是什么类型 等等 不过 需要记住一些要点 CTE 是仅对下一条语句
  • 编译 jitsi 项目时,转换为 Dalvik 格式失败,出现错误 1

    我正在尝试编译并运行该项目https github com jitsi jitsi android https github com jitsi jitsi android在 Eclipse 上通过导入 我已成功导入项目 添加了外部 Jar
  • Shopify 结账中的脚本标签

    我正在考虑为 Shopify 开发一款应用程序 该应用程序将为商店的结帐页面添加功能 如果用户不必将代码复制并粘贴到文件中 那将是理想的选择 因此我正在考虑使用 ScriptTag API http api shopify com scri
  • 为什么内部调用内的 lapply 与内部调用内的变量赋值不同?

    考虑 notBroken lt within mtcars gear lt as factor gear cyl lt as factor cyl str notBroken 我们的输出 gt str notBroken data fram
  • 将 SQL 中的 CASE 表达式转换为 SSIS 中的派生列 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions CASE WHEN CHARINDE
  • 禁用 Cypress 自动滚动

    我正在测试我的应用程序 我有很长的侧边菜单 并且我有这样的代码 cy get tab click force true 自动滚动发生在获取和单击之间 然后选定的选项卡不可见 因为顶部菜单的位置已固定 我找到了很多解决方案 但没有一个有效 到
  • 如何在 Swift iOS 应用程序中添加 Google Drive API?

    我有一个用 Swift 编写的应用程序 它已经使用了 SwiftyDropbox API 我用 cocoapods 安装了 SwiftyDropbox use frameworks 关键词 现在 当我添加这个 pod 时 Google AP
  • 在 WooCommerce 3+ 中向订单添加自定义字段

    在 WooCommerce 中 我想添加一个新的自定义字段来订单详细信息 现在我可以使用下面的代码创建一个新的自定义字段 referenceNumber 并在其中添加 ordercreated 值 update post meta orde
  • SpriteKit场景切换时的内存问题

    Ok so awhile back in testing I had a random crash with no error and I have no clue why So i went into analyze things and