gpt4 book ai didi

Objective-C,释放一个对象两次?

转载 作者:行者123 更新时间:2023-11-28 23:17:30 26 4
gpt4 key购买 nike

我最近通过一本书开始学习 Objective-C 2.0,我想知道我是否理解了这个概念。

下面是代码,它导致释放未分配的对象时出错:

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Fraction *aFraction = [[Fraction alloc] init];
Fraction *sum = [[Fraction alloc] init], *sum2;
int n, i, pow2;

[sum setTo: 0 over: 1];

NSLog (@"Enter a value for n");
scanf ("%i", &n);

pow2 = 2;
for ( i = 1; i <= n; ++i ) {
[aFraction setTo: 1 over: pow2];
sum2 = [sum add: aFraction];
[sum release];
sum = sum2;
pow2 *= 2;
}

NSLog (@"After %i iterations, the sum is %g and the fraction is %i/%i.", n, [sum convertToNum], [sum numerator], sum.denominator);
[aFraction release];
[sum release];

[pool drain];
return 0;
}

我想知道 sum 和 sum2。这是方法添加:

- (Fraction *) add: (Fraction *) f
{
Fraction *resultFraction = [[Fraction alloc] init];
int resultNum, resultDenom;
resultNum = numerator * f.denominator + denominator * f.numerator;
resultDenom = denominator * f.denominator;

[resultFraction setTo: resultNum over: resultDenom];
[resultFraction reduce];

return resultFraction;
}

让我解释一下我的想法。

对于循环的第一次迭代,sum 被分配,然后我进入add: 方法,resultFraction 被分配。返回到sum2,意思是resultFraction返回后不占用任何内存。

在循环之前分配的第一个 sum 被释放并且 sum = sum2,这意味着“在”sum2 中的对象现在“在”sum ,而sum2赋值后不占用任何内存。接下来分配一个新的resultFraction返回给sum2,一直到现在都是空闲的,以此类推,直到退出循环后sum被释放。

现在只有一个对象(add: 返回的对象),它只是被分配给 sum/sum2 (指针?或?)。然而,这并不像我想的那样——当 sum2 被分配一个新对象(由 add: 返回的对象),并且没有被释放时,甚至将该对象分配给 sum 后,前一个对象仍然存在。这意味着在 n 个赋值之后,sum2 中将有 n 个对象。因此,当我尝试在池耗尽之前同时释放 sumsum2 时,我收到了错误。错误来 self 尝试释放的第二个对象,我只能释放 任一个 sumsum2,因为它们都连接到add: 方法返回的最后一个对象?

我希望我已经足够清楚了,因为我一整天都在用头撞墙,我突然想到了,我真的希望我做对了,这样我就可以继续写这本书了。 :)

最佳答案

那是什么书?这是一些明显非标准的内存管理模式。

首先这个方法:

- (Fraction *) add: (Fraction *) f

应该返回一个自动释放的对象。目前不是。这导致调用方出现大量困惑,因为口头禅不再是“如果你想保留一个对象返回值(超出 NARC),你必须保留它”。

接下来,当您看到类似 sum = sum2; 的表达式(其中两个变量都是对象引用;Foo*)时,它完全类似于表达式 x = 5;。这是一个简单的数字赋值;没有暗示保留/释放。

周四,如果你有:

sum = [[Fraction alloc] init];
sum2 = [[Fraction alloc] init];
sum = sum2;

您刚刚泄露了 sum2 所指的 Fraction 实例。所以:

  • 将保留/释放视为增量;你增加或减少计数。只要您的增加与减少完全平衡,您就做对了。

  • Fraction *sum; 中的 sum 视为对对象的潜在引用。宣布时,它什么都不是。当您将它分配给 [[Fraction alloc] init]; 的结果时,没有任何魔法——sum 只是保存内存中 Fraction 对象的地址。


你指的是这个吗?

    sum2 = [sum add: aFraction];
[sum release];
sum = sum2;

release 释放旧的 sum,然后在下一行用对新对象的引用覆盖该指针。

尝试构建和分析该代码。它会产生警告。这本书教你如何使用不泄漏的模式进行内存管理,但绝对不是标准的。我不相信走那条路有用;事实上,您将总是有自动释放在起作用,因此,应该总是遵循系统的标准,即使在您自己完全独立的代码中也是如此。为什么要花时间学习,然后在此时取消学习不同的模式? (我完全赞成学习不同的模式和系统……只是不是在这种情况下)。

关于Objective-C,释放一个对象两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5531060/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com