SKShapeNode和CGPathRef EXC_BAD_ACCESS

时间:2016-01-11 13:51:51

标签: ios objective-c sprite-kit skshapenode cgpathref

我试图沿路径动态绘制曲线,以试图表示山脉。

我有一个返回CGPathRef的函数,它是一个指向结构的C指针。

-(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错误。

2 个答案:

答案 0 :(得分:1)

我看到三个问题。

  1. 我对SKShapeNode不是很熟悉,但从文档看起来它只是使用你给它的路径而不复制它(与UIBezierPath不同)。在这种情况下,您需要复制UIBezierPath CGPathRef之外的路径,否则在UIBezierPath发布后它将被取消分配。例如:

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

    当你完成形状节点时,你可能需要释放该路径:

    CGPathRelease(node.path);
    
  2. 您发布的代码中似乎有一些内存泄漏:您在CGPathRef中创建了newPath,并将其复制到UIBezierPath中{ {1}},永远不要删除它们。这不会导致你的问题,但它可能会导致其他人在路上。 :)

  3. 我要小心命名前缀为otherFunction的方法,因为这对Objective-C有一定的意义(见here)。请改为new

答案 1 :(得分:0)

编译器就是如果你用newXXX命名一个函数,你需要管理你的内存。所以在-otherFunction

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

创建UIBezierPath后,您应该调用

CGPathRelease(ref);