2012-04-03 103 views
0

我理解这个代码的问题:释放或自动释放的对象

- (void)subnetMaskByNumberOfSubnetBits:(id)sender{ 

    // ------- Sets the subnet mask when the user selects the number of bits 

    NSNumberFormatter *stringToNumber = [[NSNumberFormatter alloc] init];//TURN A STRING INTO A NUMBER 
    NSNumber *selectedAmountOfBits = [[NSNumber alloc] init];//CONTAINS THE SELECTED NUMBER OF BITS 

     selectedAmountOfBits = [stringToNumber numberFromString:[sender objectValueOfSelectedItem]]; 

     [self changeSubnetMaskUsingNumberOfMaskBits:selectedAmountOfBits]; 

     //RELEASE 
     [stringToNumber release]; 
     [selectedAmountOfBits release]; 
} 

我一直得到,因为事实上,我发布selectedAmountOfBits错误。 我使用allocinit初始化了对象。 为什么我不需要释放它?

回答

2

问题是,您正在将对象分配给selectedAmountOfBits 两次

NSNumber *selectedAmountOfBits = [[NSNumber alloc] init]; 

分配您拥有并将其分配给selectedAmountOfBits一个新的NSNumber对象。

selectedAmountOfBits = [stringToNumber numberFromString:[sender objectValueOfSelectedItem]]; 

分配一个新自动释放对象selectedAmountOfBits。这意味着当你做[selectedAmountOfBits release]时,你实际上试图释放一个你不拥有的对象。你也泄露了你创建的原始NSNumber,因为你失去了对它的任何引用。

解决方法是删除alloc/init行,保留自动释放的NSNumber,并摆脱释放它的行。最后的代码应该是这样的:

- (void)subnetMaskByNumberOfSubnetBits:(id)sender{ 

    // ------- Sets the subnet mask when the user selects the number of bits 

    NSNumberFormatter *stringToNumber = [[NSNumberFormatter alloc] init];//TURN A STRING INTO A NUMBER 
     NSNumber *selectedAmountOfBits = [stringToNumber numberFromString:[sender objectValueOfSelectedItem]]; 

     [self changeSubnetMaskUsingNumberOfMaskBits:selectedAmountOfBits]; 

     //RELEASE 
     [stringToNumber release]; 
} 
0

有原始代码中的一些问题,我加//下面笔者点评:

- (void)subnetMaskByNumberOfSubnetBits:(id)sender{ 
    NSNumberFormatter *stringToNumber = [[NSNumberFormatter alloc] init]; 

    //!i: The [[NSNumber alloc] init] is unnecessary. You are creating a pointer to a dummy number 
    // that is immediately overwritten in the next line 
    NSNumber *selectedAmountOfBits = [[NSNumber alloc] init]; 

    //!i: At this point, you overwrite the pointer stored in selectedAmountOfBits to point to a new 
    // NSNumber, returned by numberFromString:, and in the autorelease pool 
     selectedAmountOfBits = [stringToNumber numberFromString:[sender objectValueOfSelectedItem]]; 

    //!i: you are now leaking the number allocated via [[NSNumber alloc] init], as you no longer have 
    // a variable tracking the pointer to it 

    [self changeSubnetMaskUsingNumberOfMaskBits:selectedAmountOfBits]; 

    [stringToNumber release]; 

    //!i: You are calling -release on the number that is in the autorelease pool, not on the 
    // original number you allocated via [[NSNumber alloc] init] 
    [selectedAmountOfBits release]; 
} 

可以解决这个问题如下:

- (void)subnetMaskByNumberOfSubnetBits:(id)sender{ 
    NSNumberFormatter *stringToNumber = [[NSNumberFormatter alloc] init]; 
    NSNumber *selectedAmountOfBits = [stringToNumber numberFromString:[sender objectValueOfSelectedItem]]; 

    [self changeSubnetMaskUsingNumberOfMaskBits:selectedAmountOfBits]; 

    //!i: You still need the -release here, as stringToNumber points to the 
    // NSNumberFormatter that you created using alloc/init 
    [stringToNumber release]; 
} 
+0

感谢您为我解决问题:) – Cubia 2012-04-03 23:39:39

+0

UIAdam也是正确的 - 他在我做之前几分钟就拿到了它);) – iccir 2012-04-03 23:39:56