【问题标题】:SKShapeNode and CGPathRef EXC_BAD_ACCESSSKShapeNode 和 CGPathRef EXC_BAD_ACCESS
【发布时间】:2016-01-11 13:51:51
【问题描述】:

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

我有一个返回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);

在我重复这个动作序列几次后,我的程序中断并显示给我。

带有 EXC_BAD_ACCESS 代码的 UIApplicationMain = 2。

我知道存在内存泄漏。

我的问题是,当我最终将 CGPathRef 传递给几个函数并将其包装在另一个类中时,我该如何处理?

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

【问题讨论】:

  • 我建议您发布实际编译的代码,而不是“从 otherFunction 展开的路径”。

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


【解决方案1】:

我看到了三个问题。

  1. 我对@9​​87654322@ 不是很熟悉,但从文档看来,它只是使用了您提供的路径而不复制它(与UIBezierPath 不同)。在这种情况下,您需要将路径从UIBezierPathCGPathRef 中复制出来,否则一旦UIBezierPath 被释放,它就会被释放。例如:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    创建 UIBezierPath 后,您应该调用

    CGPathRelease(ref);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多