我在理解这段代码时遇到了问题:
- (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
和init
初始化了对象。
为什么我不需要发布它?
答案 0 :(得分: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];
}
答案 1 :(得分: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];
}