SKShapeNode 和 CGPathRef EXC_BAD_ACCESS

SKShapeNode and CGPathRef EXC_BAD_ACCESS

我正在尝试沿路径动态绘制曲线以表示山脉。

我有一个函数 returns 一个 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 with EXC_BAD_ACCESS code = 2.

我知道存在内存泄漏。

我的问题是,当我最终通过几个函数传递它并将它包装在另一个 class 中时,我该如何处理释放 CGPathRef

我更新了代码,现在收到 EXC_I386_GPFLT 错误。

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

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

创建 UIBezierPath 后,您应该调用

CGPathRelease(ref);

我看到三个问题。

  1. 我对SKShapeNode不是很熟悉,但是从文档来看它似乎只是使用你给它的路径而没有复制它(不像UIBezierPath)。在这种情况下,您需要从 UIBezierPathCGPathRef 中复制路径,否则一旦 UIBezierPath 被释放,它就会被释放。例如:

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

    完成形状节点后,您可能需要取消分配该路径:

    CGPathRelease(node.path);
    
  2. 您发布的代码中似乎存在一些内存泄漏:您正在 newPath 中创建 CGPathRef,将它们复制到 UIBezierPathotherFunction 中,永远不要删除它们。那不会导致您的问题,但可能会导致其他人。 :)

  3. 我会小心命名带有前缀 new 的方法,因为它对 Objective-C 有一定意义(参见 here)。请尝试 createPath