2012-04-03 8 views
0

Ich habe ein Problem mit diesem Code zu verstehen:Loslassen oder Autoreleasing Objekte

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

ich aufgrund der Tatsache, erhalte Fehler gehalten, dass ich selectedAmountOfBits freigegeben. Ich initialisierte das Objekt mit alloc und init. Warum muss ich es nicht veröffentlichen?

Antwort

2

Das Problem besteht darin, dass Sie selectedAmountOfBits zweimal ein Objekt zuweisen.

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

weist ein neues NSNumber Objekt, das Sie besitzen und weist sie selectedAmountOfBits.

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

ordnet eine neue Autoreleased Objekt selectedAmountOfBits. Das heißt, wenn Sie [selectedAmountOfBits release] tun, versuchen Sie tatsächlich, ein Objekt freizugeben, das Sie nicht besitzen. Sie haben auch die ursprüngliche NSNummer verloren, die Sie erstellt haben, da Sie keine Referenz mehr darauf haben.

Die Lösung besteht darin, die alloc/init-Zeile zu entfernen, die automatisch freigegebene NSNumber zu behalten und die Zeile loszulassen, in der Sie sie freigeben. Der endgültige Code sollte wie folgt aussehen:

- (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

Es gibt einige Probleme in dem ursprünglichen Code, habe ich // i Kommentare unten:

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

Sie können dieses Problem beheben, wie folgt:

- (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

Danke für die Klärung der Dinge für mich :) – Cubia

+0

UIAdam ist auch richtig - er hat es ein paar Minuten vor mir;) – iccir

Verwandte Themen