SKShapeNode имеет неограниченный рост памяти

Если я запускаю этот код в методе инициализации SKScene sublass

for (int i = 0; i < 100; i++) {

            SKShapeNode *shape = [SKShapeNode node];

            shape.antialiased = NO;

            CGMutablePathRef path = CGPathCreateMutable();

            CGPathAddEllipseInRect(path, NULL, CGRectMake(arc4random()%320, arc4random()%320, 10, 10));

            shape.path = path;

            [shape setStrokeColor:[UIColor blackColor]];

            CGPathRelease(path);

            [self addChild:shape];

            [shape removeFromParent];

        }

и каждый раз, когда я запускаю этот код в своем управляющем контроллере SKView

SKView * skView = (SKView *)self.view;

// Create and configure the scene.

SKScene * scene = [ZTMyScene sceneWithSize:skView.bounds.size];

scene.scaleMode = SKSceneScaleModeAspectFill;



// Present the scene.

[skView presentScene:scene];

мое использование памяти растет до тех пор, пока память не будет заполнена и не выйдет из строя. Этого не происходит, если я использую SKSpriteNode. Кто-нибудь исправить это?

Резюме: я создаю проект шаблона набора спрайтов, добавляю множество SKShapeNodes и заменяю старый SKScene новым.

Я добавил образец проекта на github https://github.com/zeiteisen/MemoryTest.


person zeiteisen    schedule 19.09.2013    source источник
comment
если вы можете изолировать это в минимальном проекте, и он подтверждает это поведение, сообщите об этом как об ошибке в Apple developer.apple.com/bug-reporting/using-bug-reporter   -  person LearnCocos2D    schedule 20.09.2013


Ответы (2)


Я узнал об этой проблеме, читая другой пост. Я немного возился с SKShapeNode и действительно проверил указанную здесь проблему утечки памяти.

При этом у меня возникла идея...

Идея не совсем новая, скорее переделанная. Эта замечательная идея фактически позволила мне использовать SKShapeNodes в свое удовольствие :)

ОБЪЕДИНЕНИЕ

Ага... Я только что создал пул SKShapeNodes, который повторно использовал по мере необходимости. Какая разница :)

Вы просто переопределяете путь всякий раз, когда это необходимо, когда закончите, используя возврат в свой пул, и он будет ждать, пока вы снова поиграете с ним позже.

Создайте ivar или свойство NSMutableArray в вызываемом SKScene пуле и создайте его при инициализации SKScene. Вы можете либо заполнить массив узлами формы во время инициализации, либо создать их по мере необходимости.

Это быстрый метод, который я создал для захвата нового узла из пула:

-(SKShapeNode *)getShapeNode
{
    if (pool.count > 0)
    {
        SKShapeNode *shape = pool[0];
        [pool removeObject:shape];
        return shape;
    }

    // if there is not any nodes left in the pool, create a new one to return
    SKShapeNode *shape = [SKShapeNode node];

    return shape;
}

Поэтому везде, где вам нужен SKShapeNode, вы должны сделать это:

SKShapeNode *shape = [self getShapeNode];
// do whatever you need to do with the instance

Когда вы закончите использовать узел формы, просто верните его в пул и установите путь равным NULL, например:

[pool addObject:shape];
[shape removeFromParent];
shape.path = NULL;

Я знаю, что это обходной путь, а не идеальное решение, но, безусловно, это очень жизнеспособный обходной путь для тех, кто хочет использовать большое количество SKShapeNodes и не тратить память.

person prototypical    schedule 06.05.2014

Вы добавляете форму и сразу после ее удаления, почему?

[self addChild:shape];

[shape removeFromParent]
person Juanan Jimenez Montes    schedule 27.12.2013
comment
Предположительно, чтобы продемонстрировать проблему, с которой он сталкивается, в ее простейшей форме. - person Dfowj; 29.12.2013