【问题标题】:SpriteKit Memory LeakSpriteKit 内存泄漏
【发布时间】:2015-03-25 22:33:30
【问题描述】:

分析我的应用程序后,我似乎在此方法的某处有内存泄漏:

- (void) didEvaluateActions {
for (int x = 0; x < self.children.count; x++) {
    if ([self.children[x] isKindOfClass:[BallNode class]]) {
        BallNode * ball = (BallNode *) self.children[x];

        if (abs(ball.physicsBody.velocity.dx) < BALL_MIN_VEL_X) {
            ball.physicsBody.velocity = CGVectorMake((ball.physicsBody.velocity.dx < 0 ? -1 : 1) * BALL_MIN_VEL_X, ball.physicsBody.velocity.dy);
        }

        if (abs(ball.physicsBody.velocity.dx) > BALL_MAX_VEL_X) {
            ball.physicsBody.velocity = CGVectorMake((ball.physicsBody.velocity.dx < 0 ? -1 : 1) * BALL_MAX_VEL_X, ball.physicsBody.velocity.dy);
        }

        if (abs(ball.physicsBody.velocity.dy) < BALL_MIN_VEL_Y) {
            ball.physicsBody.velocity = CGVectorMake(ball.physicsBody.velocity.dx, (ball.physicsBody.velocity.dy < 0 ? -1 : 1) * BALL_MIN_VEL_Y);
        }

        if (abs(ball.physicsBody.velocity.dy) > BALL_MAX_VEL_Y) {
            ball.physicsBody.velocity = CGVectorMake(ball.physicsBody.velocity.dx, (ball.physicsBody.velocity.dy < 0 ? -1 : 1) * BALL_MAX_VEL_Y);
        }
    }
}
}

我没有看到这种方法可能导致内存泄漏的地方。 BallNode 不是在这里创建的,那么为什么仪器会指向这个位置呢?这种方法如何导致泄漏?

-提前致谢

【问题讨论】:

  • 我遇到了同样的问题,并通过“skView.showsPhysics = false”解决了。显示物理的身体会导致内存泄漏。

标签: objective-c memory-leaks sprite-kit skshapenode


【解决方案1】:

我似乎没有做错什么,但如果你在代码中指向正确的位置,那么我认为这与self.children.count有关

试试

NSUInteger count = self.children.count;

for (NSInteger x = 0; x < count; x++)
{
    if ([self.children[x] isKindOfClass:[BallNode class]]) {
        BallNode * ball = (BallNode *) self.children[x];

        if (abs(ball.physicsBody.velocity.dx) < BALL_MIN_VEL_X) {
            ball.physicsBody.velocity = CGVectorMake((ball.physicsBody.velocity.dx < 0 ? -1 : 1) * BALL_MIN_VEL_X, ball.physicsBody.velocity.dy);
        }

        if (abs(ball.physicsBody.velocity.dx) > BALL_MAX_VEL_X) {
            ball.physicsBody.velocity = CGVectorMake((ball.physicsBody.velocity.dx < 0 ? -1 : 1) * BALL_MAX_VEL_X, ball.physicsBody.velocity.dy);
        }

        if (abs(ball.physicsBody.velocity.dy) < BALL_MIN_VEL_Y) {
            ball.physicsBody.velocity = CGVectorMake(ball.physicsBody.velocity.dx, (ball.physicsBody.velocity.dy < 0 ? -1 : 1) * BALL_MIN_VEL_Y);
        }

        if (abs(ball.physicsBody.velocity.dy) > BALL_MAX_VEL_Y) {
            ball.physicsBody.velocity = CGVectorMake(ball.physicsBody.velocity.dx, (ball.physicsBody.velocity.dy < 0 ? -1 : 1) * BALL_MAX_VEL_Y);
        }
    }
}

您目前拥有它的方式是尝试通过循环评估 self.children.count 每次迭代。这应该不会导致泄漏,但在重复评估时,可能有一些东西阻止它被正确释放。

此外,您可能希望查看 enumerateChildNodesWithName:,这比查看每个孩子并查看它是否是 BallNode 更快。

希望这是问题所在,并且很容易解决。

【讨论】:

    【解决方案2】:

    您不断创建越来越多的 BallNode 类实例。尝试在最后一个 if 语句之后添加 ball = nil;,但老实说,我不知道这是否会对您有所帮助。

    要么您的代码逻辑错误,要么您没有发布其他内容。通常,拥有一个球的 ivar 是有意义的,您可以将发布的代码应用到该 ivar 上。

    【讨论】:

    • 我必须反对。 BallNode * ball = (BallNode*)self.children[x] 只是将索引 x 处的子节点转换为 BallNode。这本身并不分配任何新对象。
    猜你喜欢
    • 2016-06-17
    • 1970-01-01
    • 2015-07-23
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    相关资源
    最近更新 更多