2016-11-28 61 views
0

编码Objective-C的项目时,我有点困惑。 ARC已打开。下面是一个示例代码:的NSString和Objective-C内存管理ARC

​​

这里是我的问题:

  1. 我需要显式地终止C字符串以“\ 0” initWithUTF8String:方法,或者它是好的省略NULL结束?

  2. 当我重新使用foo作为指针并为其指定新的Objective-C字符串时,是否有任何内存泄漏?为什么?

  3. 如果我改变NSString到其他类,如NSObject还是我自己的类,是有问题的2有什么区别? (初始化一个对象,然后直接重新指定其他值。)

谢谢!

+0

对于你的问题2:参见[这里](http://stackoverflow.com/questions/7071096/what-is-difference-between-mutable-and-immutable/36756871#36756871)基本上是有新指针创建 - 释放先前的指针。 – Honey

+0

@Honey这是一个巧妙的把戏。只需用'%p'打印出实际的指针,一切都很清晰。 –

回答

2
  1. 显式\ 0没有在C(并且因此目标C),因为需要,引用字符串文字是空终止由编译器隐式。这里有一个类似的问题。

Do string literals that end with a null-terminator contain an extra null-terminator?

  • 无内存泄漏。 ARC配置的编译器将生成代码以释放在分配新字符串之前被引用的第一个字符串。

  • 没有变化。如果类型不兼容,您可能会收到编译时警告。

  • +0

    对于1,我认为这就是为什么我在'initWithUTF8String:'中使用非NULL终止的cString几年,但从未遇到任何问题。无论如何,NULL终止一个C字符串总是一个好习惯。 –

    +2

    关键是字符串文字(“引用的代码中的字符串”)IS NULL默认终止。还有其他的方法来构造不会被NULL终止的字符串,例如一个memcpy或从一个流初始化。 – TomSwift

    +0

    好吧,只有字符串文字,像“abs”。我想这就是为什么当使用'printf'时,没有人会写'printf(“%d \ n \ 0”,12)'。大家会在这里省略'\ 0'。谢谢! –

    0

    对于第一个问题,苹果公司的官方文档告诉我的是:

    返回从UTF8编码的字节给定的C数组复制数据创建一个字符串。

    • (ID)stringWithUTF8String:(常量字符*)字节 参数 字节 在UTF8编码字节的NULL终止的C数组。

    但由于字符串是NULL默认情况下终止(如@TomSwift指出的),它的好省略。

    2
    1. 您必须空终止。从文档中:“字节 - 以UTF-8编码的以NULL结尾的C字节数组,该值不能为NULL。”
    2. 号编译器将插入前值的隐式释放并保留新的,因为你声明的(隐含的)强大的语义FOO。从文档中可以看出:“__strong是默认的,只要有一个强有力的指针,一个对象仍然是”活着的“。”
    3. 一般来说,没有。
    +3

    这是不正确的。是的,传递的UTF8编码的字符串必须包含一个空终止符。但是编译器会隐式地终止一个引用的文字字符串,这在这里被使用。 – TomSwift

    +0

    随时编辑答案。 –