我正在使用-initWithObjectsAndKeys:创建一个NSDictionary。
对于我提供给该字典的每个对象,我都会调用一个自定义方法-createFooBarObject,它将创建并返回该对象。
现在问题来了:根据定义,create方法不应该释放该对象,因为它必须返回该对象,而调用者负责释放它。但在这里,调用者没有机会释放它,因为NSDictionary会立即吸收它。我直接在对象和键的-initWithObjectsAndKeys:列表中调用该create-method,所以在添加到字典中之后,我没有机会调用-release。嗯,我可以遍历字典,然后释放它们。但那是丑陋的。
那么在-createFooBarObject方法中返回之前,它对-autorelease有效吗?我不确定-autorelease会在什么时候进行。但在字典创建并保留该对象之前,不应该发生这种情况。有什么想法吗?
发布于 2009-08-16 15:01:05
如果要调用+alloc来创建对象(看起来就是这样),则必须释放或自动释放。
如果创建的方法返回使用+alloc创建的对象,则必须返回-autoreleased对象。
另一种选择是不按设计模式所说的去做,然后处理你的不同模式和之间的阻抗不匹配。除非性能分析表明您有一个只能通过这样做来修复的性能问题,否则不要去那里。
在这种情况下,您可能希望返回一个-autoreleased对象。这样调用者就不必担心调用-release或-autorelease了。这就是它应该是的。
发布于 2009-08-16 18:43:55
对于Objective-C API,"new“表示+1引用返回值。对于CoreFoundation,"create“可以。反之亦然:"create“和"new”不能互换。
所以在Objective-C中,"createFooBarObject“表示一个自动释放的对象,根据当前的规则,你应该自动释放它。如果你真的打算返回一个+1引用对象,你应该在名称中使用"new“而不是"create”。
这些规则由clang static analyzer检查。
clang-sa还允许您通过attribute((ns_returns_retained))或attribute((cf_returns_retained)).专门对您定义的不同于常规约定的约定进行annotate methods例如,如果一个ObjC方法通过"create“返回一个新的CF对象(就像QuartzCore -CIContext createCGImage:fromRect:),那么就有一种边缘情况。如果您有这样的API,而clang-sa曲解了您的意图,那么您可以对该方法进行注释,具体说明您确实返回了一个具有特定引用类型的对象。
发布于 2009-08-17 01:20:56
注意两点:你用alloc创建一个对象,你用initWithObjectsAndKeys初始化它- alloc/init总是成对的,所以这通常只是技术上的区别。
但是更重要的是,create方法如果不是返回一个拥有的对象,你应该自动释放它。这是在memory management rules中明确指定的。鉴于该规范,以及将方法命名为"create“所造成的混乱,我建议不要在方法名称中使用"create”,而应将其命名为fooBarObject并返回一个自动释放(或无主)对象。如果你这样做了,那么你的问题就会立即解决。
那么在-createFooBarObject方法中返回之前,它对-autorelease有效吗?
它不仅是有效的,而且是绝对必需的-如果你正在自动释放的对象在那个时候属于你(即,你可以合法地调用release)。
我不确定-autorelease会在什么时候发生。
自动释放池在概念上非常简单-系统会保留指向对象的指针的副本,当自动释放池被排出/释放时,它会将release方法发送给对象。
自动释放池是嵌套的,永远不会意外地被神奇地排出-当控制流返回到创建自动释放池的人并释放它时,它们将被排出。通常这是最初调用您的代码来处理事件的run循环。
但即使是这种理解在很大程度上也是无关紧要的--只要阅读memory management rules并遵循这些规则,就不会有任何问题。
https://stackoverflow.com/questions/1284461
复制相似问题