这是一个初学者级别的问题,我很好奇这是否是在语句中有效使用指针,例如:
NSMutableDictionary *foo = [bar mutableCopy];
当有效时与我需要执行以下操作时,我感到困惑:
NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0]; foo = [bar mutableCopy]; // use foo [foo release];
两者都有效吗?何时使用一个而不是另一个?
猜测为什么你可能会感到困惑,我想补充说明第二个代码示例实际上做了什么(以及为什么没有必要).
NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0];
我认为你对这条线感到困惑,因为这条线通常被描述为"初始化foo".这有点误导.技术上在这里改变了两个不同的实体 - NSMutableDictionary
创建了新对象,并为"foo"变量分配了它的地址.
该行实际上NSMutableDictionary
在堆上创建了一个新对象(应用程序的动态内存区域).我称之为"词典1".这样就可以找到堆上的这个新的"Dictionary 1"对象,它的内存地址存储在"foo"中."foo"的作用是充当索引,所以我们可以找到"词典1".
虽然我们经常说:"foo是一本字典",那是因为我们很懒 - 这种说法在技术上是错误的.正确地说:"堆上有一个字典,foo存储它的内存地址,以便我们可以找到并使用它".
然后当你运行该行时:
foo = [bar mutableCopy];
您正在使用"bar"中的地址在堆中查找不同的对象(我将其称为"Dictionary 2"),并在堆上创建具有相同值的另一个对象("Dictionary 3").如果你保持计数,现在有三个对象存在.
在制作"Dictionary 3"之后,将其存储器地址存储在"foo"变量中.存储到"foo"中会覆盖现有的内存地址(指向"Dictionary 1"的地址).这意味着我们没有剩余指向"Dictionary 1"的指针,因此永远无法再找到它.这就是我们说"词典1"泄露的原因.
我希望你能从这种情况看出为什么从来不需要"词典1"(你只打算用"foo"来访问副本"Dictionary 3").
您永远不需要在第二个示例中编写代码.在[[NSMutableDictionary alloc] initWithCapacity:0]
不执行任何操作,除了泄漏的内存.
在第二个示例中,您将创建一个NSMutableDictionary并将其分配给foo
.然后在下一行中,您将另一个NSMutableDictionary的副本分配给foo
,这意味着foo
指向的原始字典现在只是浮动在堆上的某个地方,无法永远释放.
但是,您需要foo
在Objective-C内存管理指南中列出的任何一种情况下都要发布.