繁体   English   中英

将对象设置为nil时不调用dealloc方法

[英]dealloc method is not invoked when set an object to nil

我有个问题。

我首先创建了一个扩展NSObject的对象,我提供了描述和dealloc方法的覆盖。 这是我的Employee.m文件:

@implementation Employee
.....

-(NSString *)description
{
    return [NSString stringWithFormat:@"Employ ID: %d has $%d value of assets", [self     employeeID], [self valueOfAssets]];
}

-(void)dealloc
{   
    NSLog(@"deallocating.. %@", self);
    [super dealloc];
}

在我的main.m中,我首先创建了一个NSMutableArray来保存Employee对象列表:

NSMutableArray *employees = [[NSMutableArray alloc] init];

for (int i =0; i< 10; i++)
{
    // Create an instance of Employee
    Employee *person = [[Employee alloc] init];

    // Give the instance varaible interesting values
    [person setEmployeeID:i];
    [employees addObject: person];
}

最后我把员工定为零

employees = nil;

我期望调用每个Employee对象的dealloc方法,我会看到一些日志,如:

deallocating.. Employ ID 0 has value.....
deallocating.. Employ ID 2 has value.....
....

但是,我没有看到任何日志,如果我在dealloc方法上设置断点,则断点永远不会被命中。

有什么想法吗?

几点意见:

  1. person = nil不会在非ARC代码中释放对象。 它将在ARC代码中(至少如果它很强大)。

  2. 在ARC中,当本地对象超出范围时,它们将自动为您释放。 在非ARC中,不会为您释放超出范围的对象(如果您在其他地方没有其他对这些对象的引用,则最终会泄漏)。

  3. 将项添加到可变数组将增加项的保留计数,因此即使您在非ARC代码中包含一个版本,该对象也不会被释放,直到保留计数降至零(不仅仅通过释放来完成)将对象添加到数组后,也将对象从数组中删除。

因此,鉴于这是非ARC代码,它可能是这样的:

- (void)testInNonArcCode
{
    NSMutableArray *employees = [[NSMutableArray alloc] init]; // employees retain count = +1

    for (int i =0; i< 10; i++)
    {
        //create an instance of Employee
        Employee *person = [[Employee alloc] init]; // person retain count = +1

        //Give the instance varaible interesting values
        [person setEmployeeID:i];
        [employees addObject: person];  // person retain count = +2
        [person release];  // person retain count = +1 (YOU REALLY WANT TO DO THIS OR ELSE OR NON-ARC PROGRAM WILL LEAK)
        // person = nil;   // this does nothing, except clears the local var that's limited to the for loop scope ... it does nothing to reduce the retain count or improve memory management in non-ARC code, thus I have commented it out
    }

    // do whatever you want

    [employees removeAllObjects]; // this will remove all of the person objects and they will have their respective retain counts reduced to 0, and therefore the Employee objects will be released

    [employees release]; // employees array's own retain count reduced to zero (and will now be dealloced, itself)
}

在ARC代码中:

- (void)testInArcCode
{
    NSMutableArray *employees = [[NSMutableArray alloc] init]; // employees retain count = +1

    for (int i =0; i< 10; i++)
    {
        //create an instance of Employee
        Employee *person = [[Employee alloc] init]; // person retain count = +1

        //Give the instance varaible interesting values
        [person setEmployeeID:i];
        [employees addObject: person];  // person retain count = +2

        // person = nil;      // this would reduce person retain count to +1 (but unnecessary in ARC because when person falls out of scope, it will have it's retain count automatically reduced)
    }

    // do whatever you want

    [employees removeAllObjects]; // this will remove all of the person objects and they will have their respective retain counts reduced to 0, and therefore will be released

    // [employees release]; // not permitted in ARC
    // employees = nil;     // this would effectively release employees, but again, not needed, because when it falls out of scope, it will be released anyway
}

解放对象的正确方法就是这样做

[employees release];

将其设置为nil将不会释放内存。

由于您被允许调用[super dealloc] ,我可以假设您没有使用自动引用计数 这意味着您需要显式地将您编写的每个alloc与平衡release调用配对。 对于你来说,当你使数组为零时,你基本上泄露了员工的所有内存。 您需要再次遍历数组以释放它们,或者更好,因为您正在学习... 尽快开始编写ARC代码。

值得注意的是,ARC是针对这种情况而创建的; 它对我们的大脑有意义,现在如果你使用最新的工具它可以成为现实。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM