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

我有个问题。

我首先创build了一个扩展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中,我首先创build了一个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代码(至less如果它是强大的)。

  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] ,我可以假设你没有使用自动引用计数 。 这意味着你需要明确地将你写的每个分配与一个平衡release呼叫配对。 对于你来说,当你把数组设为零时,你基本上泄漏了员工的所有内存。 您需要再次遍历数组以释放它们,或者更好,因为您正在学习… 尽快开始编写ARC代码。

可能很重要的一点是,ARC正是为这种情况而创build的; 这对我们的大脑是有意义的,现在如果你使用最新的工具,它可以成为现实。