3

我有个问题。

我首先创建了一个扩展 NSObject 的对象,我为 description 和 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;

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

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

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

有什么想法吗?

4

3 回答 3

8

几点观察:

  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
}
于 2012-06-24T04:18:29.087 回答
3

释放对象的正确方法是

[employees release];

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

于 2012-06-24T04:04:28.327 回答
2

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

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

于 2012-06-24T04:06:16.147 回答