什么是自动释放范围?

时间:2012-01-22 15:00:19

标签: ios autorelease

在[self saveContext]之前是否有可能释放测试对象?

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Test" inManagedObjectContext:[self managedObjectContext]];
for (int i = 0; i < 10; i++) 
{
 Test *test = [[[Test alloc] initWithEntity:entity insertIntoManagedObjectContext:[self managedObjectContext]] autorelease];
 test.text = @"Text";
 test.index = [NSNumber numberWithInt:i];
}
[self saveContext];

4 个答案:

答案 0 :(得分:1)

通过自动释放范围我假设您的意思是自动释放池将被耗尽。您可以使用以下语法定义自动释放范围:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Test" inManagedObjectContext:[self managedObjectContext]];
@autoreleasepool {
    for (int i = 0; i < 10; i++) 
    {
        Test *test = [[[Test alloc] initWithEntity:entity insertIntoManagedObjectContext:[self managedObjectContext]] autorelease];
        test.text = @"Text";
        test.index = [NSNumber numberWithInt:i];
    }
    [self saveContext];
}

在正常情况下,当执行到达空闲循环时,自动释放池将被耗尽,但这可以在程序中更改。

答案 1 :(得分:1)

是肯定的。但我认为这需要一个线程。

任何时候发送一个对象-autorelease,它都会被添加到最高级别的自动释放池中。只要您不在方法B中创建任何新的自动释放池或在调用堆栈中创建任何新的自动释放池,方法A的池应该是最高级别的池。

来自此处 What is the scope of (nested) autorelease pools?

答案 2 :(得分:0)

不,除非在几个特定的​​情况下,并让我们找出原因。假设这是在主线程上,在调用选择器之前,系统将在您的函数之前为您创建NSAutoreleasePool,然后在之后。

因此,如果展开时,您的代码如下所示:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Test" 
inManagedObjectContext:[self managedObjectContext]];
for (int i = 0; i < 10; i++) 
{
 Test *test = [[[Test alloc] initWithEntity:entity insertIntoManagedObjectContext:[self managedObjectContext]] autorelease];
 test.text = @"Text";
 test.index = [NSNumber numberWithInt:i];
}
[self saveContext];
[pool drain];
函数退出后会立即释放

entity,即[self saveContext]之后。如果你选择启用它,ARC会解决很多这些问题。

警告!

请注意,这不是苹果使用的实际代码,池只是每帧都耗尽,而不是每个方法,但是当内存耗尽时,自动释放池会自动耗尽,因此,如果你的设备内存不足,从理论上讲,这可能导致实体提前释放,但如果发生这种情况,您还有其他问题需要担心。

另请注意,在处理线程时,您必须创建自己的自动释放池,系统不会为您执行此操作。这不是你在这里做的,但如果确实发生了这种情况,请记住将选择器包装在@autorelease块中。

答案 3 :(得分:0)

简单说明:
如果您自己不使用自动释放池,则所有对象在方法,函数或块中都是安全的。