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);
我看到三个问题。
我对SKShapeNode
不是很熟悉,但是从文档来看它似乎只是使用你给它的路径而没有复制它(不像UIBezierPath
)。在这种情况下,您需要从 UIBezierPath
的 CGPathRef
中复制路径,否则一旦 UIBezierPath
被释放,它就会被释放。例如:
SKShapeNode *node = [SKShapeNode new];
CGPathRef pathCopy = CGPathCreateCopy(/* path from other function unwrapped */);
node.path = pathCopy;
...
完成形状节点后,您可能需要取消分配该路径:
CGPathRelease(node.path);
您发布的代码中似乎存在一些内存泄漏:您正在 newPath
中创建 CGPathRef
,将它们复制到 UIBezierPath
在 otherFunction
中,永远不要删除它们。那不会导致您的问题,但可能会导致其他人。 :)
我会小心命名带有前缀 new
的方法,因为它对 Objective-C 有一定意义(参见 here)。请尝试 createPath
。
我正在尝试沿路径动态绘制曲线以表示山脉。
我有一个函数 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);
我看到三个问题。
我对
SKShapeNode
不是很熟悉,但是从文档来看它似乎只是使用你给它的路径而没有复制它(不像UIBezierPath
)。在这种情况下,您需要从UIBezierPath
的CGPathRef
中复制路径,否则一旦UIBezierPath
被释放,它就会被释放。例如:SKShapeNode *node = [SKShapeNode new]; CGPathRef pathCopy = CGPathCreateCopy(/* path from other function unwrapped */); node.path = pathCopy; ...
完成形状节点后,您可能需要取消分配该路径:
CGPathRelease(node.path);
您发布的代码中似乎存在一些内存泄漏:您正在
newPath
中创建CGPathRef
,将它们复制到UIBezierPath
在otherFunction
中,永远不要删除它们。那不会导致您的问题,但可能会导致其他人。 :)我会小心命名带有前缀
new
的方法,因为它对 Objective-C 有一定意义(参见 here)。请尝试createPath
。