从方法内部给出以下代码片段;
NSBezierPath * tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
[tempPath retain];
[path release];
[self setPath:tempPath];
我有责任发布tempPath
还是会为我完成?
setPath是@synthesize
d所以我可能也可以省略[path release]
?
我知道更好的方法就是这样做;
[path appendBezierPathWithOvalInRect:pathRect];
但是,作为Objective C和Cocoa的新手,我正在努力理解事物是如何结合在一起的。
---增加的内容
退出[tempPath retain]
会导致使用路径的NSView
对象崩溃。
调试器的结果:
(gdb) po [0x145dc0 path] Program received signal EXC_BAD_ACCESS, Could not access
存储器。 原因:地址为0x00000021的KERN_PROTECTION_FAILURE objc_msgSend()中的0x93c56688
GUILT的诅咒 - 我的错误。希望别人能从我的错误中获得有用的东西。我在assign
声明中使用retain
代替@property
。修复那些使代码按预期工作的方法。
感谢帮助人员
答案 0 :(得分:3)
如果path
是支持-setPath:
方法的实例变量,那么不,您绝对不应该在-dealloc
方法之外发布它。您不需要手动保留tempPath
对象,因为您正在使用访问者来保存该对象。您的访问者,-setPath:
,在这种情况下,-init
和-dealloc
方法应该是您在实例变量上调用-retain
和-release
的唯一方法
您的代码也可以像这样工作,并且内存泄漏的可能性更小:
NSBezierPath *tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
[self setPath:tempPath];
由于-bezierPathWithOvalInRect:
方法返回一个自动释放的对象,并且您的访问者将保留它,因此您不需要对其进行任何其他操作。
答案 1 :(得分:1)
您无需释放tempPath。
您也可以删除[tempPath retain]
和[path release]
。通过合成set方法来处理这些。
答案 2 :(得分:1)
让我们看看另一种方式:
如果您没有使用合成访问器,那么您将自己编写它们。在最简单的形式中,它们看起来像这样:
- (NSBezierPath *) path {
return path;
}
- (void)setPath:(NSBezierPath *)newPath {
if (path == newPath) {
// both objects have the same pointer so are the same.
return;
}
[path release];
path = [newPath retain];
}
您可以看到旧路径已释放且新路径保留在setter中,因此您无需在方法中执行此操作,可以将其写为
self.path = [NSBezierPath bezierPathWithOvalInRect:pathRect];