2016-11-28 98 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

    隨時編輯答案。 –