2010-01-29 127 views
12

在以下来自核心数据编程指南的代码示例中,NSFetchRequest创建为 autorelease,而NSSortDescriptor不是使用autorelease创建的。为什么不使用autorelease创建NSSortDescriptor?这是一个偏好问题吗?自动发布或不自动发布

NSManagedObjectContext *moc = [self managedObjectContext];  
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" 
                inManagedObjectContext:moc]; 

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
[request setEntity:entityDescription]; 
// Set example predicate and sort orderings... 
NSNumber *minimumSalary = ...; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c]'Worsley') AND (salary > %@)", minimumSalary];  
[request setPredicate:predicate]; 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" 
                   ascending:YES]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[sortDescriptor release]; 
NSError *error; 
NSArray *array = [moc executeFetchRequest:request error:&error]; 
if (array == nil){ 
    // Deal with error... 
} 

回答

35

当你autorelease,你基本上说:“我不再需要这个,但任何人都可以自由地选择它(在自动释放池被耗尽之前)”。当你明确地发布一个对象时,你会说:“我不再需要它了,除非其他人已经说过(已获得),应该立即释放它。”

因此,自动释放通常不是说错话。当你想把对象传回给消息的发送者而不需要发送者负责释放该对象时,它是需要

+1

这是我为autorelease读过的最简洁的解释。 – TechZen 2010-01-30 00:14:25

+0

的确很好答案! +! – 2011-04-10 02:37:58

26

自动释放还是不自动释放

的问题。

编码器是否因内存泄漏的吊索和箭头而受到崇高的崇敬,或者是对指定的海洋采取武器并保留它们,结束它们......这是一个虔诚的希望!是的,有蹭! ...对于那些过度释放的对象,当我们引用不存在的对象必须让我们暂停时,可能会发生什么崩溃。

我忍不住自己。我会接受重创。我一点儿都不后悔!

+0

+0:你已经得到了四分之一:) – 2010-03-21 22:55:39

+0

+1:绝对的辉煌。 – 2010-09-03 19:47:40

+0

有趣,但在寻找真正的答案时会受到阻碍。 – finnw 2013-11-29 00:12:02

0

现在的问题是:如何使用autoreleaserelease影响对象的生命周期?

在您的两个例子都没有差别。

两个NSFetchRequest和NSSortDescriptors会活着直到方法结束,不管他们是否正在释放或自动释放。

如果你创建一个对象的实例,然后把它给另一个物体(比如一个NSArray),它将仍然活着,无论你是否调用释放或自动释放。

-1

都保留并自动释放,功能保留的对象,但他们不合并。区别在于保留计数只能由另一个对象递减,而自动释放计数在NSAutoreleasePool耗尽时自动递减。如果没有其他对象在游泳池耗尽时保留了自动释放对象,它就会变成流行的。

基本上,你可以使用自动释放,当你要确保对象在当前方法中徘徊,并可以传递到其他对象,但你不希望有自己跟踪其释放。

在你的示例代码,自动释放只是一种安全措施。 NSPredicate对象因其作业已完成而被释放,但编码人员希望确保NSFetchRequest对象挂起。在这个例子中,你不必使用“autorelease”,但是如果你丢失了你的版本,fetchRequest可能会消失。另一方面,你不希望它成为孤儿并泄漏,所以你使用autorelease来清理当对象处于漏水状态的池。

autorelease最常见的用法是每次创建可变数量的对象时。你不需要跟踪它们,因此你可以自动释放它们,让游泳池照顾它们。 (更好的是,创建一个本地池并在完成后尽快将其排空)。

在Apple API标准中,创建没有关键字'init','new'或'create'的新对象的任何方法'返回一个自动释放的对象。

-[NSString initWithString:]不是autorelease,但 - [NSString stringWithString:]是。这会在非垃圾收集环境中导致问题,因为stringWithString:返回一个字符串,该字符串的行为看起来像保留的对象,但稍后它会在自动释放池在漏斗中创建时突然消失。


Edit01:从Apple文档

自动释放池是“包含”已经收到了 自动释放消息 其他对象 NSAutoreleasePool的实例;当 自动释放池被解除分配时,它将向这些对象的每个 发送释放消息。一个对象可以将 放入几个 时间的自动释放池中,并且每次将其放入 池时都会收到一个释放消息 。因此,自动释放发送代替 释放到对象 在 至少延伸该对象的寿命,直至池本身是 释放(如果它被保持在临时 对象可能存活 更长)。

保留计数和autorelease都通过相同的基本(但是单独的)计数机制保持对象的存活。主要区别是拥有对象发送版本。保留计数,它的另一个对象,但对于autoreleased计数它的自动释放池。

+0

autorelease不保留一个对象。 – 2010-01-29 23:46:39

+0

我澄清,是更好的? – TechZen 2010-01-30 00:09:15

1

请求对象将返回给调用者,而sortDescriptor正在使用,然后被丢弃。

autorelease的基本原理很简单。如果没有它,任何从函数返回的对象都需要被调用者释放,如果他们不需要的话。使用autorelease意味着函数可能会返回一个对象,如果调用者不关心它们,或者如果他们打算看它而不保留对它的引用,那么它们就可以使用它而无需添加额外的代码来释放它。只有他们保留参考,他们才需要保留它。

值得思考autorelease是什么意思。当你在一个对象上调用autorelease时,它会将该对象添加到一个列表中,当你的应用程序循环结束时,它会释放一个对象。这使autorelease完全等同于延迟发布。

关于内存管理的apple文档非常好,值得仔细阅读。 http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html