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];
}

をリリースしたため、エラーが発生し続けましたselectedAmountOfBitsallocとを使用してオブジェクトを初期化しましたinit。なぜリリースする必要がないのですか?

4

2 に答える 2

2

問題は、オブジェクトを selectedAmountOfBits に2 回割り当てていることです。

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 に答える