Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 将对象设置为nil时不调用dealloc方法_Objective C_Ios - Fatal编程技术网

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

Objective c 将对象设置为nil时不调用dealloc方法,objective-c,ios,Objective C,Ios,我有个问题 我首先创建了一个扩展NSObject的对象,为description和dealloc方法提供了覆盖。这是我的Employee.m文件: @implementation Employee ..... -(NSString *)description { return [NSString stringWithFormat:@"Employ ID: %d has $%d value of assets", [self employeeID], [self valueOfA

我有个问题

我首先创建了一个扩展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来保存员工对象列表:

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];
}
我希望调用每个Employee对象的
dealloc
方法,我会看到一些日志,如:

deallocating.. Employ ID 0 has value.....
deallocating.. Employ ID 2 has value.....
....
但是,我没有看到任何日志,如果我在
dealloc
方法上设置了一个断点,那么这个断点永远不会被命中


有什么想法吗?

释放对象的正确方法是

[employees release];

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

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


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

一些观察结果:

  • person=nil
    不会释放非ARC代码中的对象。它将在ARC代码中显示(至少如果它很强的话)

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

  • 将项添加到可变数组将增加项的保留计数,因此即使在非ARC代码中包含释放,对象也不会被释放,直到保留计数降至零(通过在将person对象添加到数组后释放person对象,并将其从数组中移除来实现)

  • 因此,鉴于这是非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)
    }
    
    -(无效)测试非随机码
    {
    NSMutableArray*员工=[[NSMutableArray alloc]init];//员工保留计数=+1
    对于(int i=0;i<10;i++)
    {
    //创建Employee的实例
    员工*person=[[Employee alloc]init];//人员保留计数=+1
    //给实例变量指定有趣的值
    [person setEmployeeID:i];
    [employees addObject:person];//person retain count=+2
    [person release];//person retain count=+1(您确实要这样做,否则非ARC程序将泄漏)
    //person=nil;//除了清除限制在for循环范围内的本地变量之外,它什么都不做……它对减少非ARC代码中的保留计数或改进内存管理没有任何作用,因此我将其注释掉
    }
    //你想干什么就干什么
    [employees removeAllObjects];//这将删除所有person对象,并且他们各自的保留计数将减少到0,因此employees对象将被释放
    [employees release];//employees数组自身的保留计数减少为零(现在将自行解除分配)
    }
    
    在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
    }
    
    -(无效)代码
    {
    NSMutableArray*员工=[[NSMutableArray alloc]init];//员工保留计数=+1
    对于(int i=0;i<10;i++)
    {
    //创建Employee的实例
    员工*person=[[Employee alloc]init];//人员保留计数=+1
    //给实例变量指定有趣的值
    [person setEmployeeID:i];
    [employees addObject:person];//person retain count=+2
    //person=nil;//这会将person retain count减少到+1(但在ARC中没有必要,因为当person超出范围时,它将自动减少其retain count)
    }
    //你想干什么就干什么
    [employees removeAllObjects];//这将删除所有person对象,并且他们各自的保留计数将减少到0,因此将被释放
    //[员工释放];//在ARC中不允许
    //employees=nil;//这将有效地释放employees,但同样不需要,因为当它超出范围时,无论如何都会释放它
    }
    
    谢谢ctrahey,我已经将我的项目转换为ARC。现在它可以工作了,我不需要再打电话给[super dealoc]问题已经通过将我的项目转换为ARC解决了:编辑>重构>转换为Objective-C ARC,有关ARC的更多信息,这应该是公认的答案。我不认为“更改为ARC”正确回答这个问题,因为这个问题意味着此人出于某种原因没有使用ARC(这可能是故意的),这个答案是解释性的,也解释了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
    }