ios - SKShapeNode 和 CGPathRef EXC_BAD_ACCESS

标签 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 with EXC_BAD_ACCESS code = 2.

我知道存在内存泄漏。

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

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

最佳答案

我看到了三个问题。

  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,将它们复制到 otherFunction 中的 UIBezierPath,永远不要删除它们。那不会导致您的问题,但可能会导致其他人。 :)

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

关于ios - SKShapeNode 和 CGPathRef EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34723208/

相关文章:

ios - WatchOS2 WCSession WCSession 在 WatchKitExtension 中可以有多少个委托(delegate)?

ios - 如何在 iOS 中播放来自服务器的流式 PCM 数据?

objective-c - Mac OS X App 在使用 NSPopovers 时向后兼容 10.6 和 10.7

ios - UITableViewController 内的 UINavigationBar

iphone - 用于在 Iphone sdk 中进行视频电话 session 的 API?

ios - 如何在每增加 50 点后加速 Sprite Kit 游戏

ios - 类型 "GameScene"不符合协议(protocol)“SKPaymentTransactionObserver

ios - 检测哪个 viewController 呈现了 SideMenu 并为其呈现实现适当的功能

ios - 在运行时更改标签节点文本。 .

swift - 初学者 swift Sprite 工具包 - 节点碰撞检测帮助(SKPhysicsContact)