解释 alloc/init 发生两次
我知道这个问题可能听起来很愚蠢,但请耐心听我说。我构建了一个应用程序来帮助新开发人员了解 iPhone 上的内存保留(还没有 ARC)。它简单明了,4 个按钮,初始化、访问、保留和释放。非常不言自明。我正在显示我的字符串对象的保留计数,该对象是我们戳和戳的目标。 (请不要讲授 [myVar keepCount] 的使用,我已经知道了)
这个东西永远不会进入实际的应用程序,只是为了好玩而玩弄它,希望能帮助人们了解内存是如何工作的。我的保留和释放都工作得很好。我的问题是,如果我调用 myString = [[NSMutableString alloc] init]; 为什么我的保留计数会回落到 1再次。我可以将保留计数增加到 40,但在调用 alloc/init 后我又回到零。我没有泄漏任何地方,只是好奇如果/当再次调用 alloc/init 时 myString 会发生什么。
I realize this question may sound dumb, but just bear with me. I built an app to help new developers wrap their head around memory retention on the iPhone (no ARC yet). It is plain and simple, 4 buttons, init, access, retain, and release. Pretty self explanatory. I am displaying what the retain count for my string object that is the target of our poking and prodding. (Please no lectures on use of [myVar retainCount], I already know)
This stuff will never make it into actual apps, just toying with it for fun and hopefully help someone learn how memory works. My retain and release all work great. My question is that why does my retain count drop back to 1 if I call myString = [[NSMutableString alloc] init]; again. I can boost my retain count to 40, but after calling alloc/init I go back to zero. I am not leaking anywhere, just curious what happens to myString if/when alloc/init is called on it again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因为你没有理解 Objective-C 的一个非常基本的概念;
myString
不是NSMutableString
的实例,而是对实例的引用。如果您这样做:您现在有两个 NSMutableString 实例,其中一个已泄漏。
如果您:
您现在有一个带有两个引用的 NSMutableString 实例。
在所有三个分配中,NSMutableString 实例的保留计数将+1,因此,您必须用单个
release
来平衡每个分配,否则就会发生泄漏。将保留计数视为绝对计数是一条通往疯狂的道路。或者,充其量,绝对保留计数的有用范围非常有限,以至于学习它不适用于现实世界的 iOS 编程。
值得重复的是:
对象的
retainCount
是一件棘手的事情。如果您要继续沿着这条路走,您应该注意以下细节:
retainCount
永远不能返回 0retain
/release
/autorelease
不会工作,因为有些类实际上并不使用这些方法来维护保留计数(实现细节、每个平台/版本的更改等。)如果您要教授保留/释放,您应该对待保留算作增量并完全关注“如果您增加 RC,就必须减少它”。
Because you are failing to understand a very basic concept of Objective-C;
myString
is not an instance of anNSMutableString
, but a reference to an instance. If you were to:You now have two instances of NSMutableString, one leaked.
If you:
You now have a single instance of NSMutableString with two references.
In all three allocations, the NSMutableString instance will have a +1 retain count and, thus, you must balance each with a single
release
or you'll leak.Treating retain counts as an absolute count is a path to madness. Or, at best, the scope of usefulness of the absolute retain count is so limited that learning about it is not applicable to real world iOS programming.
This bears repeating:
The
retainCount
of an object is tricky business.If you were to continue down this path, you should be aware of the following details:
retainCount
can never return 0retain
/release
/autorelease
won't work as some classes don't actually use those methods to maintain the retain count (implementation detail, changes per platform/release, etc..)If you are going to teach retain/release, you should be treating the retain count as a delta and focus entirely on "If you increase the RC, you must decrease it".
当您调用 myString = [[NSMutableString alloc] init]; 时,您并不是“再次调用 alloc/init”。您没有在您拥有的同一实例上调用方法。您正在分配并初始化一个新实例,这是一个与之前的对象完全不同的对象。
如果您使用一个包含您保留的对象的变量来执行此操作,那么是的,您正在泄漏它。
when you call
myString = [[NSMutableString alloc] init];
, you're not "calling alloc/init on it again". You're not calling a method on the same instance you had. You're allocating and initializing a new instance, a completely different object from the one you had before.And if you're doing that with a variable that had an object that you retained, then yes, you are leaking it.
试试这个。
您会看到,您有一个具有新保留计数的不同对象。您的原始对象仍然存在并且仍然具有相同的保留计数。赋值改变了变量引用的对象。变量没有保留计数,而对象有。
保留财产:
Try this.
You see, you have a different object with a new retain count. Your original object still exists and still has the same retain count. Assignment changes the object a variable refers to. A variable doesn't have a retain count, an object does.
With retained property: