- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近通过一本书开始学习 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 个对象。因此,当我尝试在池耗尽之前同时释放 sum
和 sum2
时,我收到了错误。错误来 self 尝试释放的第二个对象,我只能释放 任一个 sum
或 sum2
,因为它们都连接到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/
我有一个附加了 View Controller 的 AVAudioPlayer 实例。 @property (nonatomic, retain) AVAudioPlayer *previewAudi
我是java初学者。假设我声明了一个 Account 类型的变量 Account _account = new Account("Thomas"); 然后在其他地方我做了这样的事情: _account
我在我的应用程序中使用了 3 个 UIViewController,现在我想知道当我从另一个应用程序切换到另一个 UIViewController 时释放它们是否是一个好主意。显然,这将是隐藏的,当它
我分配了一个直接缓冲区: ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 我读过: Deallocating Direct Buf
场景。我有一个图表,我可以使用右键单击来执行平移。这非常有效。然后我完美地添加了右键菜单。 问题。现在,即使在拖动操作完成后释放鼠标,也会显示右键菜单。 有没有办法在 Java Swing 或 Jav
我使用此代码获取 ABPerson 的姓氏 CFStringRef lastNameRef = ABRecordCopyValue((ABRecordRef)personRecordRef, kABP
目前,我们在基于 C 的嵌入式应用程序中使用 malloc/free Linux 命令进行内存分配/取消分配。我听说这会导致内存碎片,因为内存分配/取消分配会导致堆大小增加/减少,从而导致性能下降。其
当我尝试释放缓冲区时遇到问题。每次我尝试将缓冲区传递给释放方法时,都会发生段错误。 Valgrind 确认段错误位于 BufferDeallocate 方法中。 ==30960== Memcheck,
我想知道何时按下或释放修改后的键(Ctrl 或 Shift)。 基本上,用户可以在按下修改键的情况下执行多次击键,而我不想在它被释放之前执行一个操作(想想 Emacs 和 Ctrl + X + S).
我编写了一个相当大的网络应用程序。它运行良好一段时间,然后慢慢开始运行缓慢,因为 DOM 节点开始爬升到 80,000 - 100,000 左右。 所以我一直在 Chrome 开发工具控制台 (DCT
我知道在像 c 这样的语言中,我需要在分配内存后释放它。 (我来自 Java),对此我有几个问题: 当我在做的时候: int array[30]; (即创建一个大小为 30 个整数的数组)与
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How to release pointer from boost::shared_ptr? Detach
我有一个可以从多个后台线程访问的类,可能同时访问。我无法复制该类,因为重新创建它的内容(处理或内存方面)可能很昂贵。 也有可能在后台处理仍在继续并访问该属性时替换了此类的属性。 目前我有定期的保留/释
这个问题是对: 的扩展链接-1:Creating an image out of the ios surface and saving it Link-2:Taking Screenshots fro
我有一个实例变量 NSMutableArray* searchResults。 首先,我初始化它: self.searchResults = [[NSMutableArray alloc] init]
如果我在堆上声明一些东西,比如 char *a=new char[1000] 并且主程序停止,如果没有 delete[]<,那么分配的内存会发生什么 调用?它保留在堆上还是自动释放? 最佳答案 就C+
在开发相机应用时,我遇到了一个异常,该异常仅在我切换到其他应用时发生(onPause() 用于我的应用)。 01-15 17:22:15.017: E/AndroidRuntime(14336): F
使用 JDK 1.8 编译时出现 maven 编译器错误 无法执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (de
将 BufferedImage 保存到磁盘(以释放内存)的最快方法是什么? 我的 Java 应用程序处理大量图像(每约 300 毫秒将图像加载到内存中)。大多数这些图像都会立即被丢弃 (gc),但每隔
使用 JDK 1.8 编译时出现 maven 编译器错误 未能在项目 DUMMY 上执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:
我是一名优秀的程序员,十分优秀!