4

我仍在思考 Objective-C 中内存管理的一些细微差别,并提出了以下我不确定的案例:

+ (NSDecimalNumber*)factorial: (NSDecimalNumber *)l {

    NSDecimalNumber *index = l;
    NSDecimalNumber *running = [NSDecimalNumber one];

    for (; [index intValue] > 1; index = [index decimalNumberBySubtracting:[NSDecimalNumber one]]) {
        running = [running decimalNumberByMultiplyingBy: index];
    }
    return running;
}

在这里,decimalNumberByMultiplyingBy 和 decimalNumberBySubtracting 将创建很多 NSDecimalNumber,据我了解,它们最终会自动释放,但我担心直到那个时候包含的程序会占用大量内存。

我应该在某处引入自动释放池吗?(如果是在哪里?)这是否会对性能产生显着影响(与使用大量内存的副作用相比)?

自动释放在这里使用正确的机制吗?我是否应该考虑将循环分开并在完成后手动释放内存?

这可能是一个 n00b 问题,但我试图了解在这种情况下最佳实践是什么。

4

3 回答 3

5

避免在一次运行循环中创建大量自动释放的大型对象是一种很好的做法。您似乎已经知道解决方案。您可以使用非自动释放的对象并在使用完它们后释放它们。您还可以为创建大量自动释放对象的代码部分创建自动释放池。当一个对象被自动释放时,它会在封闭的自动释放池被释放/耗尽时被释放。使用自动释放池如下所示:

NSAutoReleasePool *subPool = [[NSAutoreleasePool alloc] init];
// Code that generates a bunch of autoreleased objects.
[subPool release];

但是,在您进行任何优化之前,请运行一些基准测试,看看您是否真的需要优化。我的猜测是您展示的方法不会引起任何问题。但是,假设您正在尝试将您的方法应用于单个循环中的一百万个随机整数的集合。在这种情况下,您可能会从使用自动释放池中受益。

查看 Apple 的 Cocoa 内存管理编程指南了解更多详情。

于 2010-10-07T02:24:16.700 回答
1

确定答案的最佳方法是用几种不同的方式编写它并进行测试。我不认为这会是一个问题,但是,NSDecimalNumbers 将最大约为 100!,而 100 个 NSDecimalNumber 对象可能不会有什么不同。


回答您的其他问题:在重要的情况下,您可以手动释放您的对象。您还可以在该循环内创建一个自动释放池。自动释放速度超级快

while(/*condition*/) {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // code goes here

    [pool drain];
}
于 2010-10-07T02:08:31.647 回答
1

你可以在循环中设置一个自动释放池,但是为什么要麻烦呢?

您将无法在此循环中累积那么多对象,因为您正在计算阶乘,并且NSDecimalNumber可以拥有的最大指数是 127。

在循环进行 100 次迭代之前,您将收到溢出错误。

请注意,每次应用程序通过主运行循环时,主自动释放池都会清空,因此自动释放的值不会停留很长时间。

于 2010-10-07T02:08:38.377 回答