记忆分配问题

时间:2011-07-19 23:35:11

标签: iphone objective-c xcode retain alloc

我有一个字符串,我不断更新(每秒约33次)。它被一遍又一遍地使用,并且在我已经开始的循环中无处不在。这是循环:

- (void)add{
    int r = (arc4random() % 30) + 51;
    long long debtInt = [debtString longLongValue];
    long long multiplier = r;
    long long debtAdj = multiplier + debtInt;
    debtString = [NSString stringWithFormat:@"%lli", debtAdj];
    [debtString retain];
    [self formating];
}

- (void)formating{
    NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
    [f setNumberStyle:NSNumberFormatterDecimalStyle];
    NSNumber * myNumber = [f numberFromString:debtString];
    [f release];

    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [numberFormatter setMaximumFractionDigits:0];
    NSString *formattedNumberString = [numberFormatter stringFromNumber:myNumber];
    [numberFormatter release];

    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 325, 100)];
    myLabel.font = [UIFont fontWithName:@"Verdana" size: 20.0];
    myLabel.text = formattedNumberString;
    myLabel.textAlignment = UITextAlignmentCenter;

    [self.view addSubview:myLabel];
    [myLabel release];
}

每隔0.03秒由NSTimer触发。我认为可以在逻辑上释放debtString的一个地方是在它被转换为长整数之后。然而,这会使应用程序崩溃。如果我删除[debtString retain]行,则应用会崩溃。

内存构建快速而快速,它是一个14字节的字符串。每秒创建另外462个字节的错误分配内存,以及所有调整,大约为3696个/秒。这不是我可以忽略的泄漏。我只是不知道在循环中将它释放到哪里!

4 个答案:

答案 0 :(得分:4)

如果您承诺以这种方式执行此操作,则应在重新分配值之前在循环的每次迭代中释放debtString

[debtString release];    
debtString = [NSString stringWithFormat:@"%lli", debtAdj];
[debtString retain];

但是,您每个循环都在创建一个新实例。使用单个NSMutableString(如@OscarMk建议)并每次更新它都会更好。并且每次都不要创建新的UILabel。只需创建一个并在每次循环时更新内容。

答案 1 :(得分:2)

如果经常更新NSMutableString,你应该特别使用它。

答案 2 :(得分:0)

当您使用stringWithNumber:方法时,您将返回自动释放池中的字符串。当你回到事件循环时,这些会被释放。

而是使用显式alloc和init:

[debtString release];  // release previous (if any)
debtString = [[NSString alloc] initWithFormat:@"%lli", debtAdj];

如果debtString是一个保留的@property,这就是setter会为你做的事情。

高度咖啡因是正确的,每次都不要创建新的UILabel,只需更新文本字段即可。对于NSNumberFormatter也是如此,将其保存为实例变量,这样您就不必每次都创建它(然后只将它添加到子视图一次)。

答案 3 :(得分:0)

问题是我每次都在声明变量,而不是在标题中合成它们。在十分钟内修好了。