NSString是否需要分配内存空间!

3
我正在scrollViewDidScroll方法中运行此代码(因此它会在滚动时运行!):

NSString *yearCount = [[NSString alloc] initWithFormat:@"%0.1f", theScroller.contentOffset.y];  
years.text = yearCount; 
[yearCount release];

这段代码的功能很好,但是在滚动时会影响性能(导致减速抖动)。

我的问题是,我是否需要继续使用alloc和release,或者有没有一种方法可以使用initWithFormat将一些数字添加到文本中而不需要它们?

3个回答

3
years.text = [NSString stringWithFormat:@"%0.1f", theScroller.contentOffset.y];

使用自动释放池可以避免显式释放字符串的需要。

如果您想要避免减速,考虑减少更新字段的频率。例如,每次调用scrollViewDidScroll时,设置一个计时器,在0.1秒后更新字段,但如果计时器已经从先前的调用运行,则不进行更新。这样可以减少调用次数,同时保持UI更新。


以下是如何实现的示例。在滚动视图代理的接口声明中声明一个NSTimer

NSTimer *timer;

方法:

- (void)updateYear:(NSTimer*)theTimer
{
    timer=nil;
    UIScrollView *theScroller=[theTimer userInfo];
    years.text=[NSString stringWithFormat:@"%0.1f", theScroller.contentOffset.y];
}

- (void)scrollViewDidScroll:(UIScrollView *)theScroller
{
    if (!timer) {
        timer=[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updateYear:) userInfo:theScroller repeats:NO];
    }
}

显然,您不必使用0.1作为时间间隔,您可以尝试加快或减慢速度,看看哪种效果最好。

请注意,就内存管理而言,此示例已经完整,您不应尝试自己保留或释放计时器对象。它的生命周期由运行循环在内部处理。


1
这只是一个方便的方法,它在幕后分配字符串。它不是一种替代方法。 - Chuck
我现在已经添加了一个更完整的答案。 - Nick Moore
有什么好的Timer示例(链接)可以分享吗?这会是非常有帮助的.. (我也会去找,我不是在偷懒哈哈) - mtompson
就内存管理而言,在 - (void)dealloc 中释放 'timer' 就可以了吗? - mtompson
@Mark,你不应该自己释放计时器,因为你没有对其进行allocretaincopy操作。每个计时器实例都会被运行循环内部保留,并在计时器失效后自动释放,这通常发生在计时器触发后(请参阅NSTimer类参考文档:http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html)。就内存管理而言,这个示例已经完整了。 - Nick Moore

2
考虑使用scrollViewDidEndDecelerating方法来避免频繁更新。分配-初始化不会导致性能下降,频繁设置文本会导致性能下降。除非你真的需要连续更改它(在这种情况下,使用定时器的解决方案可能是一个选项),否则应该寻找另一个钩子方法。

谢谢Thomas,我确实需要这个功能,所以计时器选项看起来不错。 - mtompson

1

你的性能问题绝对不是由于字符串格式化或分配释放造成的。你可以使用一些更短的形式,比如:

years.text = [NSString stringWithFormat:@"%0.1f", theScroller.contentOffset.y];

这相当于

years.text = [[[NSString alloc] initWithFormat:@"%0.1f", theScroller.contentOffset.y] autorelease];

然而,这并不能帮助你提高性能。


为什么还要费心去使用alloc版本呢!? - mtompson
@Mark,有时您可能不想自动释放字符串,这种情况下您可以使用alloc而不是autorelease。因此,alloc/release可以给您更精细的控制,但是当您无论如何都会自动释放字符串时,stringWithFormat更方便。 - Nick Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接