我是Objective-C的新手,所以这可能是一个愚蠢的问题。
我不禁看到ObjC与微软COM在内存管理方面的相似之处(AddRef
/ Release
vs retain
/ release
)。在COM环境中,在将对象返回给调用者之前,总是AddRef
(retain
)对象或多或少地强加给你。从我到目前为止看到的(我是第三个到Cocoa® Programming for Mac® OS X (3rd Edition)),内存管理部分有些模糊。
假设没有GC,返回对象的惯用方法是什么?
答案 0 :(得分:12)
阅读有关自动释放池的Memory Management Programming Guide。
在Objective-C中,按照惯例,应该自动释放对象(除非返回对象的方法的名称以“alloc”,“new”,“copy”或“mutableCopy”开头)。自动释放的对象由池中的Objective-C跟踪并自动处理,这意味着您无需关心向它们发送最终版本。与COM相比,这大大简化了引用计数,这就是为什么在大多数情况下你没有看到对返回对象的任何release
调用。相反,相同的约定指定由名称以alloc,new,copy或mutableCopy开头的方法返回的所有对象都是方法调用者的责任。您必须手动调用这些对象的释放,否则您的程序将有内存泄漏。
答案 1 :(得分:5)
Cocoa通过引入第三个兄弟来绕过COM中AddRef
/ Release
的限制; autorelease
。
retain
- 我需要这个,让它坚持下去。release
- 我不再需要它了,你可以立即删除它。autorelease
- 我不需要这个,但让它保持几秒钟以防其他人想先拿起它。这个微小的添加允许大多数返回值为句柄 as-if 我们有垃圾收集。如果您对保持返回值不感兴趣,请不要做任何额外的事情。
为了实现这个目的,有一个约定(一个足够好的惯例,让编译器能够为即将到来的ARC自动为你做内存):
alloc
copy
new
retain
在实践中如何应用它的三个示例实现:
-(NSString*)newHelloWorldString {
NSString* s = [NSString stringWithString:@"Hello world"];
// Apply retain because s in now autoreleased
return [s retain];
}
-(NSString*)helloWorldString {
NSString* s = [[NSString alloc] initWithString:@"Hello world"];
// Apply autorelease because s is now retained.
return [s autorelease];
}
-(NSString*)fullName {
// No memory management needed, everything is autoreleased and good.
NSString* fn = [self firstName];
NSString* ln = [self lastName];
NSString* s = [NSString stringWithFormat:@"%@ %@", fn, ln];
return s;
}
答案 2 :(得分:1)
通常类似
return [object autorelease];
你可以留在另一端。
如果您计划在Lion / iOS5上部署或使用最新的SDK,那么请查看ARC。
答案 3 :(得分:-1)
基本上我会建议让接收它的类保留它。即stackoverflow类接收对象的答案。
即
-(void) setAnswer:(Answer*) _answer{
self.answer = _answer; // If the answer is created from a returned message.
[_answer release];
}
编辑:我想我可能已经把错误的东西放在那里,因为我正在第二次看它。意思是:
Answer *_answer = [stackoverflow createAnswer];
self.answer = _answer;
[_answer release];
答案 4 :(得分:-3)
如果你返回一个对象,由所有者来保留它,我会尽可能避免自动释放,因为一旦nspool启动,那些对象就会消失,如果它们仍然被使用,它将导致问题。
即答案*答案= [stackoverflow getAnswer],如果在getanswer方法中创建了答案,则任何人正在检索它,负责释放它。
有道理吗?