自动释放或不自动释放

时间:2010-01-29 22:25:28

标签: objective-c iphone

在“核心数据编程指南”的以下代码示例中,创建了NSFetchRequest 自动释放,而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...
}

5 个答案:

答案 0 :(得分:35)

当你自动发布时,你基本上是在说:“我不再需要这个,但是其他任何人都可以自由选择它(在自动释放池耗尽之前)”。当你明确地重新发送你所说的一个对象时:“我不再需要它了,除非其他人已经另有说明(已获得),否则应该立即取消分配。”

因此,自动释放通常不是错误的。当您想要将对象传递回邮件的发件人而不要求发件人负责释放对象时, required

答案 1 :(得分:26)

  

自动释放或不自动释放

这个问题。

对于编码人员来说,是否更高尚地遭受记忆泄漏的吊索和箭头,或者通过保留他们的武器来对抗他们,结束他们......这是一个虔诚的完美的祝福!是啊,有擦! ...对于那些过度释放的对象,当我们引用不存在的对象时,可能会发生什么崩溃。

我忍不住了。我会接受搜索。我没有后悔!

答案 2 :(得分:1)

答案 3 :(得分:0)

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

在你的两个例子中都没有区别。

NSFetchRequest和NSSortDescriptors都会一直存在,直到方法结束,无论它们是被释放还是自动释放。

如果您创建一个对象的实例,然后将其提供给另一个对象(例如,NSArray),无论您是否调用release或autorelease,它都将保持活动状态。

答案 4 :(得分:-1)

保留和自动释放,功能保留对象,但它们不合并。不同之处在于保留计数只能由另一个对象递减,而自动释放计数在NSAutoreleasePool耗尽时自动递减。如果没有其他对象在池耗尽时保留了自动释放的对象,那么它就会失败。

基本上,当你想确保一个对象在当前方法中挂起并且可以传递给其他对象但你不想自己跟踪它的发布时,你使用autorelease。

在您的示例代码中,自动释放只是一种安全措施。 NSPredicate对象已发布,因为它的工作已完成,但编码器希望确保NSFetchRequest对象挂起。在这种情况下,您不必使用“autorelease”,但如果丢失了释放次数,则fetchRequest可能会消失。另一方面,您不希望它成为孤立和泄漏,因此当对象在排水沟中时,您使用自动释放来清理。

自动释放的最常见用途是每次创建可变数量的对象时。您不希望全部跟踪它们,因此您自动释放它们并让池照顾它们。 (更好的是,你创建了一个本地游泳池,并在完成后立即将其排干。)

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

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


Edit01:来自Apple文档

  

autorelease pool是一个实例   NSAutoreleasePool“包含”   已收到的其他对象   自动释放消息;当。。。的时候   自动释放池被解除分配   向每个发送一条发布消息   那些对象。可以放置一个对象   进入自动释放池几个   次,并收到发布消息   因为它每次被放入   池。因此,发送自动释放   而不是释放到对象   延长该对象的生命周期   至少直到游泳池本身   释放(对象可能存活   如果它保留在。更长   临时)。

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