问题描述
我遇到了一个问题:在具有类似结构的更大项目中,我从仪器工具中获得内存泄漏。
如果你把它放在 Xcode 中并运行,你应该看到一条向右移动然后向左移动的线。 当按下 Button 时,Line 跳转到定义的位置。 如果您使用内存泄漏工具,点击按钮后会出现错误。我不知道为什么。这是一个错误吗?我在代码中有一个基本错误吗?如何避免这种情况?
这是将动画计算与 SwiftUI 连接起来的正确方法吗,我将 SKScene 作为 ObservableObject 并将动画标记为 @Published 以执行此动画?
感谢您的回答。
在泄漏工具中有一个注释,负责的框架是:
[nsxpcconnection remoteObjectProxyWithErrorHandler:]
感谢阅读,示例代码如下: 概述
动画计算
import SwiftUI
import SpriteKit
struct MyAnimation{
var lenght:CGFloat = 0 //Position of the line end
var up: Bool = true //if the line is moving to right or left
mutating func change(){
self.up ? (lenght += 1) : (lenght -= 1)
if lenght > 100{
up = false
}else if lenght < 0{
up = true
}
}
}
更新SKScene
class GameScene: SKScene,ObservableObject{
@Published var ani: MyAnimation //handles the calculation
override init(){
ani = MyAnimation()
super.init(size: CGSize(width: 200,height: 100))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func update(_ currentTime: TimeInterval) {
ani.change() //new Position is calculated
}
}
内容视图
struct ContentView: View {
@StateObject var game = GameScene()
var body: some View {
vstack{
ZStack{
SpriteView(scene: game).opacity(0)
MyPath().environmentObject(game)
}
Start().environmentObject(game)
//Button to let the line jump to the defined position
}
}
}
动画路径
struct MyPath: View{
@EnvironmentObject var game: GameScene
var body: some View{
Path{ path in
path.move(to: CGPoint(x: 50,y: 50))
path.addLine(to: CGPoint(x: 200 + game.ani.lenght,y: 220))
//here is the length property of the MyAnimation struct and should cause the redraw
path.closeSubpath()
}
.stroke(Color.black,linewidth: 4)
}
}
按钮
struct Start: View { //Button
@EnvironmentObject var game: GameScene
var body: some View {
Button(action: {
game.isPaused = true
game.ani.lenght = 30
game.isPaused = false
},label: {
Text("Start")
})
}
}
用于复制粘贴
import SwiftUI
import SpriteKit
struct MyAnimation{
var lenght:CGFloat = 0 //Position of the line end
var up: Bool = true //if the line is moving to right or left
mutating func change(){
self.up ? (lenght += 1) : (lenght -= 1)
if lenght > 100{
up = false
}else if lenght < 0{
up = true
}
}
}
class GameScene: SKScene,height: 100))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func update(_ currentTime: TimeInterval) {
ani.change() //new Position is calculated
}
}
struct ContentView: View {
@StateObject var game = GameScene()
var body: some View {
vstack{
ZStack{
SpriteView(scene: game).opacity(0)
MyPath().environmentObject(game)
}
Start().environmentObject(game)
//Button to let the line jump to the defined position
}
}
}
struct MyPath: View{
@EnvironmentObject var game: GameScene
var body: some View{
Path{ path in
path.move(to: CGPoint(x: 50,linewidth: 4)
}
}
struct Start: View { //Button
@EnvironmentObject var game: GameScene
var body: some View {
Button(action: {
game.isPaused = true
game.ani.lenght = 30
game.isPaused = false
},label: {
Text("Start")
})
}
}
解决方法
我可以使用以下代码重现相同的泄漏:
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Start()
}
}
}
struct Start: View {
var body: some View {
Button(action: {
},label: {
Text("Start")
})
}
}
如果没有对这个问题有更深入的了解,我会假设您不对泄漏负责,但 Apple 是。
如果您仍然希望使用 SwiftUI,我认为您现在别无选择,只能忽略泄漏。
顺便说一下,我在使用 SwiftUI 时遇到了更严重的问题,我暂时放弃了它,因为我认为它还没有准备好。