检测到上下文泄漏,msgtracer 返回 -1 (Swift 3)
Context leak detected, msgtracer returned -1 (Swift 3)
运行 Xcode 8.2 在 Swift 操场上。它还使 Xcode 没有响应。这是我遇到的错误。
Context leak detected, msgtracer returned -1
我已将问题追溯到这些代码行
while (true){
let rotate = SKAction.rotate(toAngle: angle - CGFloat(M_PI_2), duration: 1)
crank.run(rotate)
}
当我注释掉 while 循环并只保留内部时,它工作正常。
while (true){
部分将使该循环永远执行,您的代码可能不会超出该点。如果你想要一个动作永远重复,有一个 SKAction 方法 - 看看 repeat
.
如果您删除 while (true){
条件并改为使用 repeat
操作,我相信您的代码应该 运行 没问题。
@Fahim 100% 正确,根据发布的代码,您陷入了无限循环。所以你的问题是如何摆脱它?
你的问题是 - 如何让这个循环做你需要的事情。我猜想您想将条件更改为 while (someVar == true) 并将条件 inside 放入您的循环中将 someVar 更改为 false。但只有你知道那个条件是什么。语法为:
let someVar = true
while (someVar == true){
let rotate = SKAction.rotate(toAngle: angle - CGFloat(M_PI_2), duration: 1)
crank.run(rotate)
if someCondition == isMet { // THIS IS FOR YOU TO DECIDE!
someVar = false
}
}
我最终完全重写了它并使用 SKAction.repeatForever 到 运行 一个 SKAction(旋转)并且只有在条件为假时才终止。
crank.run(
SKAction.repeatForever (
SKAction.sequence([
SKAction.wait(forDuration: 0.1),
SKAction.run({
let angle = atan2(self.point.y - crank.position.y , self.point.x - crank.position.x)
let rotate = SKAction.rotate(toAngle: angle - CGFloat(M_PI_2), duration: 0.25)
crank.run(rotate)
if(!(crank.frame.contains(self.point))) {
self.removeAction(forKey: "New Thread")
}
})
])
),
withKey: "New Thread"
)
我用更多的singletong解决了这个问题。例如单件循环中的 SKView()。
我认为现有的答案在这里没有抓住要点。您有两个 "threads" 正在处理:活动线程 运行 例程(它将尽可能快地将新的旋转动作泵入节点的动作列表)和动作处理线程(这实际上不是 "thread" 本身,但可以想象为这个问题的目的)这是实际执行旋转动作的地方。
本质上,在给定的时间片中,"main" 执行线程可能会将 100k "rotate" 个动作泵入节点的动作列表,SpriteKit 引擎将同时高效地处理所有这些动作尽可能(我相信通过删除重复的操作,但我对此并不乐观)。
结果是你做的工作比你必须做的多得多,并且在你的自旋循环和 SKAction 处理代码中燃烧 CPU 试图从添加到节点每次处理。
按照 Fahim 的建议,将其替换为重复动作,这样你就可以了。然后你只需要某种触发器来停止动作(给它一个名字来结束一个动作,或者当触发器触发时停止这个节点上的所有动作)。
运行 Xcode 8.2 在 Swift 操场上。它还使 Xcode 没有响应。这是我遇到的错误。
Context leak detected, msgtracer returned -1
我已将问题追溯到这些代码行
while (true){
let rotate = SKAction.rotate(toAngle: angle - CGFloat(M_PI_2), duration: 1)
crank.run(rotate)
}
当我注释掉 while 循环并只保留内部时,它工作正常。
while (true){
部分将使该循环永远执行,您的代码可能不会超出该点。如果你想要一个动作永远重复,有一个 SKAction 方法 - 看看 repeat
.
如果您删除 while (true){
条件并改为使用 repeat
操作,我相信您的代码应该 运行 没问题。
@Fahim 100% 正确,根据发布的代码,您陷入了无限循环。所以你的问题是如何摆脱它?
你的问题是 - 如何让这个循环做你需要的事情。我猜想您想将条件更改为 while (someVar == true) 并将条件 inside 放入您的循环中将 someVar 更改为 false。但只有你知道那个条件是什么。语法为:
let someVar = true
while (someVar == true){
let rotate = SKAction.rotate(toAngle: angle - CGFloat(M_PI_2), duration: 1)
crank.run(rotate)
if someCondition == isMet { // THIS IS FOR YOU TO DECIDE!
someVar = false
}
}
我最终完全重写了它并使用 SKAction.repeatForever 到 运行 一个 SKAction(旋转)并且只有在条件为假时才终止。
crank.run(
SKAction.repeatForever (
SKAction.sequence([
SKAction.wait(forDuration: 0.1),
SKAction.run({
let angle = atan2(self.point.y - crank.position.y , self.point.x - crank.position.x)
let rotate = SKAction.rotate(toAngle: angle - CGFloat(M_PI_2), duration: 0.25)
crank.run(rotate)
if(!(crank.frame.contains(self.point))) {
self.removeAction(forKey: "New Thread")
}
})
])
),
withKey: "New Thread"
)
我用更多的singletong解决了这个问题。例如单件循环中的 SKView()。
我认为现有的答案在这里没有抓住要点。您有两个 "threads" 正在处理:活动线程 运行 例程(它将尽可能快地将新的旋转动作泵入节点的动作列表)和动作处理线程(这实际上不是 "thread" 本身,但可以想象为这个问题的目的)这是实际执行旋转动作的地方。
本质上,在给定的时间片中,"main" 执行线程可能会将 100k "rotate" 个动作泵入节点的动作列表,SpriteKit 引擎将同时高效地处理所有这些动作尽可能(我相信通过删除重复的操作,但我对此并不乐观)。
结果是你做的工作比你必须做的多得多,并且在你的自旋循环和 SKAction 处理代码中燃烧 CPU 试图从添加到节点每次处理。
按照 Fahim 的建议,将其替换为重复动作,这样你就可以了。然后你只需要某种触发器来停止动作(给它一个名字来结束一个动作,或者当触发器触发时停止这个节点上的所有动作)。