【问题标题】:Is this a valid use of an Objective-C pointer?这是对 Objective-C 指针的有效使用吗?
【发布时间】:2009-03-20 21:18:31
【问题描述】:

这是一个初学者级别的问题,我很好奇这是否是在语句中有效使用指针,例如:

 NSMutableDictionary *foo = [bar mutableCopy];

我感到困惑的是什么时候是有效的,什么时候我需要做以下事情:

NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0];
foo = [bar mutableCopy];
// use foo
[foo release];

两者都有效吗?什么时候使用一个而不是另一个?

【问题讨论】:

    标签: iphone objective-c cocoa cocoa-touch


    【解决方案1】:

    猜测您可能会感到困惑的原因,我想解释一下第二个代码示例的实际作用(以及为什么没有必要)。

    NSMutableDictionary *foo = [[NSMutableDictionary alloc] initWithCapacity:0];
    

    我认为您对这一行感到困惑,因为这行通常被描述为“初始化 foo”。这有点误导。从技术上讲,这里更改了 2 个不同的实体——创建了新的 NSMutableDictionary 对象,并为“foo”变量分配了它的地址。

    该行实际上在堆(您的应用程序的动态内存区域)上创建了一个新的NSMutableDictionary 对象。我将其称为“字典 1”。这样可以在堆上找到这个新的“字典1”对象,它的内存地址存储在“foo”中。 “foo”的作用是充当索引,所以我们可以找到“字典1”。

    虽然我们经常说:“foo 是一本字典”,但那是因为我们很懒——这种说法在技术上是错误的。正确:“堆上有一个字典,foo存储了它的内存地址,以便我们可以找到它并使用它”。

    然后运行该行时:

    foo = [bar mutableCopy];
    

    您正在使用“bar”中的地址在堆中查找不同的对象(我将其称为“字典 2”),并在堆上创建另一个具有相同值的对象(“字典 3”) .如果您继续计数,现在存在 3 个对象。

    “字典 3”制作完成后,其内存地址将存储在“foo”变量中。这种存储到“foo”中会覆盖现有的内存地址(指向“Dictionary 1”的那个)。这意味着我们没有剩余的指向“字典 1”的指针,因此将永远无法再次找到它。这就是为什么我们说“字典 1”已经泄露。

    我希望您能从这种情况中看出为什么永远不需要“字典 1”(您只打算使用“foo”来访问副本“字典 3”)。

    【讨论】:

      【解决方案2】:

      您永远不需要编写第二个示例中的代码。 [[NSMutableDictionary alloc] initWithCapacity:0] 除了泄漏内存之外什么都不做。

      在第二个示例中,您创建一个 NSMutableDictionary 并将其分配给 foo。然后在下一行中,将另一个 NSMutableDictionary 的副本分配给 foo,这意味着 foo 指向的原始字典现在只是漂浮在堆上的某个位置,永远无法释放。

      不过,无论哪种情况,您都需要释放 foo,如 Objective-C memory management guidelines 中所述。

      【讨论】:

      • 次要更正:该行之后的分配是泄漏内存的原因。但是,我同意您的观点,即永远不应该编写此代码。 :-)
      【解决方案3】:

      第一个是正确的,第二个是内存泄漏,因为你分配了两次(复制算作一次)并且只释放了一次。

      完成后别忘了释放 foo

      【讨论】:

      • 不要释放它。 mutableCopy 返回一个自动释放的对象。
      • 来自文档:然而,方法的调用者负责释放返回的对象。
      • @NilObject:再次阅读内存管理指南。 -mutableCopy 是一种复制方法。
      【解决方案4】:

      赋值操作会覆盖该变量保存的先前值。例如:

      x = 3
      x = 4
      

      第二行开头的x持有的值是3,但在这行代码执行后是4。语法:

      int x = 0;
      

      实际上只是这个的简写:

      int x;
      x = 0;
      

      作为指针的变量也不例外。因此,如果变量的第一个引用只是简单地分配给它,您不需要先初始化它,因为您初始化它的任何值都将被丢弃。

      【讨论】:

        【解决方案5】:

        第一个是正确的方法。 copy 和 alloc 都会为您的变量分配内存。因此,使用第二个选项会将变量的保留计数增加到 2。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多