内存管理,应该在这种情况下发布吗?

时间:2008-12-13 01:28:27

标签: objective-c

从方法内部给出以下代码片段;

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。修复那些使代码按预期工作的方法。

感谢帮助人员

3 个答案:

答案 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];