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. alloc我使用and初始化了对象init。为什么我不需要释放它?

4

2 回答 2

2

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

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

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

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];
}
于 2012-04-03T23:35:23.753 回答
0

原始代码中存在一些问题,我在下面添加了 //!i 注释:

- (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];
}
于 2012-04-03T23:37:30.960 回答