【问题标题】:@"" type of string and releasing an object you don't own question@"" 类型的字符串并释放您不拥有的对象
【发布时间】:2011-10-09 15:26:01
【问题描述】:

一个菜鸟问题。

如果我有一个字符串@“你好我是一个字符串”。 @"" 是一个对象吗?它是什么 ?它存储在哪里?

如果我释放一个不是我创建的对象会发生什么?或者它的并发症是什么?

NSString *string1 = [[NSString alloc] initWithString:@"string"];
NSString *string2 = string1;
[string2 release];

还有一个问题有什么区别?

NSString *string1 = [[NSString alloc] initWithString:@"string"];
NSString *string2 = @"string";

我知道我是菜鸟,但我只是想知道。

提前致谢

编辑:

我的意思是说 alloc initWithString 而不是 stringWithString

【问题讨论】:

    标签: iphone objective-c ios ipad


    【解决方案1】:

    NSString *string2 = string1;

    这不会创建新对象。 string1 不是对象,它是指向对象的指针。该赋值只是复制指针并将其放在string2

    由于实现细节(内部实现细节可能并非在所有情况下都是正确的,并且永远不应依赖),这是正确的:

    NSString *string1 = [NSString stringWithString:@"string"];
    string1 == @"string"; // this is a true expression
    

    字符串常量 -- @"dddd" -- 由编译器编译成二进制文件。它们不能被释放,每个唯一字符串只有一个常量。 stringWithString: 识别常量并且不制作新副本。

    现在,如果你要这样做:

    NSMutableString *string1 = [NSMutableString stringWithString:@"string"];
    NSMutableString *string2 = string1;
    [string2 release];
    

    将@"string" 复制到 NSMutableString 的新实例中,而 string1 将指向该对象。

    不过,该代码将是过度释放([string1 release]; 也会如此),因为 stringWithString: 返回一个自动释放的对象。

    现在,如果你要:

    NSMutableString *string1 = [[NSMutableString alloc] initWithString:@"string"];
    NSMutableString *string2 = string1;
    [string2 release];
    

    那么就保留计数而言,该代码在技术上是正确的;字符串对象将被释放。 但是release 之后,string1string2 都将是悬空指针——也就是说,它们持有的地址不再指向可行的对象,并且尝试向其中任何一个发送消息都会产生未定义的结果。

    【讨论】:

    • 要明确...允许string1 == @"string"; 处理[NSString stringWithString:@"string"]; 返回与@"string" 相同的构造字符串与特殊比较无关的实现细节,指针只是发生是一样的。
    【解决方案2】:

    当您使用@"" 语法时,您正在创建一个对象。它是创建不可变字符串的简写,在幕后也称为NSConstantString。字符串常量存储在应用程序二进制文件的数据段部分中,并与代码一起加载到内存中并在运行时引用。

    正如其他人所提到的,任何时候你没有明确地为一个对象分配空间,你不应该释放它。任何时候你过度释放一个对象,你都会给你的应用程序带来意想不到的,而且通常是随机的问题。 @Radu 的解释很到位。

    【讨论】:

      【解决方案3】:

      切勿释放不属于您的物品。规则很简单:只有使用newallocretaincopy(简称NARC)获得的对象,您才拥有该对象。

      通过任何其他方法获得的对象应自动释放返回。这意味着该对象将在下一次自动释放池耗尽时自动释放。如果你想保留这个对象,你需要retain它然后release它。如果您不关心在当前范围内完成使用对象后是否会释放该对象,那么不要对它做任何事情。

      所以,总结一下:

      • 您必须将任何 NARC 与 release 配对
      • 您必须将任何非 NARC 与 release 配对
      • 非 NARC 方法将返回 autoreleased 对象
      • 如果您需要超出当前范围的任何autoreleased 对象,您必须retain

      解决您的具体问题:

      • @"Hello i am a string" 是一个对象。它是NSConstantString 的一个实例,它是在编译时创建的。你不能也不应该release它。它将在应用程序的整个生命周期中持续存在。请查看this question 了解更多信息。
      • 如果您释放一个不属于您的对象,那么您将减少其保留计数,并且您将导致假定它不能保留它的代码的复杂性。

      【讨论】:

      • 对不起,我已经知道那么多了。这不是我要找的答案。
      【解决方案4】:

      当对象的所有者试图释放它并且它已经被释放时,释放一个不是你创建的对象最终会得到你和 EXC_BAD_ACCESS 异常。

      关于你的第二个问题,有一个很好的讨论here

      【讨论】:

      • 如果我错了,请纠正我。这告诉我 string2 基本上保留了一个指向 string1 的指针,如果我释放 string1 会有一个 EXC_BAD_ACCESS 以防原始所有者(具有 +1 保留计数)释放它并因此释放它。非常感谢您。我只需要知道@"" 是什么,它是一个对象还是存储在堆中?告诉我你是否知道我在哪里可以找到答案。我只是好奇。 :D
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 2015-09-05
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多