【问题标题】:NSString basics - memory - retain - copyNSString 基础 - 内存 - 保留 - 复制
【发布时间】:2010-02-02 10:05:20
【问题描述】:

这是我的代码:

NSString *xyz=[NSString stringWithFormat:@"%i %@",10,@"Sagar"];

现在我取的是其他字符串,如下。

NSString *x2=[xyz copy];

我不知道这里会发生什么?是不是像,x2 有 xyz 的 ref 的 ref?

NSString *x3=[xyz retain];

这里会发生什么,x3 有一个复制字符串的新内存或 [xyz 复制] 这样做?

现在,如何从内存中删除所有这三个字符串?

【问题讨论】:

  • 这里的标题并不能特别代表您正在寻找的问题。为了未来读者的利益,您会改进它吗?我认为您是在询问变量操作是否获取变量的副本或引用。一个好的方法是将标题表述为一个英文问题,例如“NSString 上的 'copy' 和 'retain' 有什么区别?”不过我不使用 Objective C,所以我不确定我的措辞是否正确。

标签: iphone objective-c memory-management nsstring


【解决方案1】:
NSString *xyz=[NSString stringWithFormat:@"%i %@",10,@"Sagar"];

这将创建自动释放的 NSString 实例 - 它将在自动释放池耗尽时释放(通常在下一个运行循环中)。

NSString *x2 = [xyz copy];

理论上-copy 消息将创建一个新的对象实例,保留计数为 1(即您必须在某处释放它),但由于 NSString 对象是不可变的,因此 [xyz 复制] 将被优化为 [xyz 保留]因此它将指向同一个实例。

NSString *x3=[xyz retain];

x3 将指向与 xyz(和 x2)相同的实例,并且它的保留计数将增加 - 您必须在某处释放您的对象。

现在,如何删除所有这三个 内存中的字符串?

确保将所有保留(复制)消息与释放配对,并且内存将被释放。
阅读Objective-c memory management guide了解更多详情。

【讨论】:

  • 一个autoreleased 对象将在下一次添加到它的池被耗尽时被释放。对于具有运行循环的应用程序,应用程序的主池通常会在运行循环的下一次迭代中耗尽。
  • 是的dreamlax,看来我需要自己修改内存管理文档:)
  • 我不能同意你的最后一段。字符串 [xyz/x3] 应该释放一次,字符串 x2 应该释放一次。即使您使用的库的实现恰好使它们成为相同的实例,您的代码也应该假设 x2 是对象的副本,而不是引用。有一天你的“copy==same object”假设会被打破。
  • @Graham Lee。同意你的观点,删除了
【解决方案2】:

在这种情况下,熟悉与 Objective-c 和 cocoa(以及相关框架)中的内存管理相关的消息命名约定/规则特别有帮助:

如果你拥有一个对象的所有权 使用其名称的方法创建它 以“alloc”或“new”或 包含“copy”(例如,alloc, newObject 或 mutableCopy),或者如果您 向其发送保留消息。你是 负责放弃 您拥有的对象的所有权 释放或自动释放。任何其他时间 你收到一个对象,你不能 释放它。 (Memory Management Programming Guide for Cocoa)

因此,您可以假设,您从未根据上述方案命名的消息中收到的每个对象要么自动释放,要么通过其他方式处理(它可能是由其他一些物体等)

只要牢记这一点,您的问题就能很快得到解答:

  1. 您从一条消息中收到 NSString *xyz,该消息的名称与上述规则中描述的方案不匹配(不是分配、不是新建、不是复制、不是保留)。你不能释放它。

  2. 您从名为 copy 的消息中收到 NSString *x2。你必须释放它

  3. 您从名为 retain 的消息中收到 NSString *x3。你必须释放它。

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 2019-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2010-10-09
    • 2011-07-31
    • 2012-03-05
    • 1970-01-01
    相关资源
    最近更新 更多