2016-01-11 4 views
0

Я пытаюсь динамически рисовать кривые вдоль пути, пытаясь представить горы.SKShapeNode и CGPathRef EXC_BAD_ACCESS

У меня есть функция, которая возвращает CGPathRef, который является указателем на структуру.

-(CGPathRef)newPath 
{ 
    CGMutablePathRef mutablePath = CGPathCreateMutable(); 
    //inserting quad curves, etc 
    return mutablePath; 
} 

Я затем передать эти CGPathRefs вокруг, обернув их в UIBezierPath.

-(NSArray*)otherFunction 
{ 
    CGPathRef ref = [self newPath]; 
    UIBezierPath *path = [UIBezierPath bezierPathWithCGPath: ref]; 
    NSArray* paths = @[path]; 
    CGPathRelease(ref); 
    return paths; 
} 

Я тогда взять возвращенный массив путей и отображать их на экране с помощью SKShapeNode.

SKShapeNode *node = [SKShapeNode new]; 

NSArray* paths = [self otherFunction]; 
CGPathRef ref = [[paths firstObject] CGPath]; 

node.path = ref; 
node.fillColor = [UIColor orangeColor]; 
node.lineWidth = 2; 

И, наконец.

[self addChild:node]; 
CGPathRelease(node.path); 

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

UIApplicationMain с EXC_BAD_ACCESS кодом = 2.

Я понимаю, что это утечка памяти.

Мой вопрос в том, как обращаться с выпуском CGPathRef, когда я передаю его через несколько функций и завершу его в другой класс?

Я обновил код и теперь получаю ошибку EXC_I386_GPFLT.

+0

Предлагаю вам опубликовать фактический код, который компилируется вместо «путь из другойФункции, развернутой». – 0x141E

ответ

1

Я вижу три проблемы.

  1. Я не очень хорошо знаком с SKShapeNode, но из документации это выглядит, как он просто использует путь, который вы даете ему без его копирования (в отличие от UIBezierPath). В этом случае вам нужно скопировать путь из UIBezierPathCGPathRef, потому что в противном случае он будет освобожден после освобождения UIBezierPath. Например:

    SKShapeNode *node = [SKShapeNode new]; 
    CGPathRef pathCopy = CGPathCreateCopy(/* path from other function unwrapped */); 
    node.path = pathCopy; 
    ... 
    

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

    CGPathRelease(node.path); 
    
  2. Похоже, у вас есть некоторые утечки памяти в коде, публикуемую: вы создаете CGPathRef s в newPath, копируя их в UIBezierPath в otherFunction и никогда не удаляя их. Это не вызовет вашей проблемы, но это может привести к тому, что другие будут двигаться по дороге.:)

  3. Я бы стал осторожным методом именования с префиксом new, поскольку это имеет значение для Objective-C (см. here). Вместо этого попробуйте createPath.

0

Вещь с компилятором - если вы называете функцию с помощью newXXX, вам нужно управлять своей памятью. Таким образом, в -otherFunction

-(NSArray*)otherFunction 
{ 
    CGPathRef ref = [self newPath]; 
    UIBezierPath *path = [UIBezierPath bezierPathWithCGPath: ref]; 
    NSArray* paths = @[path]; 
    return paths; 
} 

после создания UIBezierPath, вы должны вызвать

CGPathRelease(ref);