2012-01-30 9 views
12

Objective-Cのポインタの値が何かを割り当てるまで定義されていないことを示唆するさまざまな人物/記事(例:this SO answer)が見つかりました。宣言時にポインタは常にnilに設定されていますか?

NSString* foo;   // 1 
assert(foo==nil);  // foo is nil 
foo = [NSString alloc]; // 2 
assert(foo!=nil);  // after alloc, not nil. 
foo = [foo init];  // 3 
assert(foo!=nil);  // still not nil 

/私はこれに依存している必要がありますすることができ:次のコードは、アサートすることなく、私のために動作します - しかし、私は、彼らは自動的に私はallocを呼び出す前であってもnilに設定されていることを実際に見つけていますか?それは保証されているのですか、または何らかのデバッグモードでコンパイラ(Xcode)を実行していますか? (私はObjective-Cの新機能です)。

結果的な質問:fooを1,2,3と記された行の最後に記述する正しい用語は何ですか? 1 & 2のうち少なくとも1つは「初期化されていない」と呼ばれ、2 & 3のうちの1つは「初期化」されていますが、それはどのようなものですか。

+0

テスト成功成功

NSString *testStr = nil; if (testStr == nil) { NSLog(@"Test Successful"); } 

OutPut :テストが初期化され

NSString *testStr ; if (testStr == nil) { NSLog(@"Test Successful"); } 

OutPut : ARC環境でOBJ-Cでのテストを実行し、 。エラーなしです。 – theWalker

+1

http://stackoverflow.com/questions/3989377/xcode-compiler-doesnt-set-my-variable-and-pointer-initial-value-to--0-or-nilの可能な複製 –

答えて

25

、ポインタが初期化時にnilに設定されているすべてのオブジェクト。 ARCの下で実行されていないとき、または他のデータ型へのポインタを使うとき、初期化されていないポインタはガベージ値を持ちます(実際にはポインタからの読み取りはC標準に従って未定義の動作を生成します)。


@Chuckは、これがローカル変数にのみ適用されることを指摘しています。静的記憶域(関数の静的またはグローバル)とインスタンス変数を持つ変数は、常にそれぞれのゼロ値(ポインタの場合はnil/NULL)に初期化されます。

+7

これはローカルの非静的変数にのみ当てはまることに注意してください。オブジェクト型のグローバル変数、静的変数およびインスタンス変数*は、標準に従ってnilに初期化されます。 – Chuck

+0

@Chuck:とても良い点。私はそれに応じて私の答えを更新します。 –

+0

これを記載した文書にリンクできますか?私はARCリンクが持っていると思ったが、それはそうではないようだ(私は 'nil'のページを検索した) – bacar

6

(ARCについては、ケビンの回答を参照してください)

/私はこれに頼る必要がありますすることはできますか?

これは決して頼りません。スタックメモリは通常、デバッグビルドでゼロになります(コンパイラの設定によって異なります)。最適化を有効にすると、コンパイラはそれを実行せず、最後にスタック領域に存在したものに基づいてガベージ値が与えられます。

には、オブジェクトのイニシャライザでゼロを付けたivarsが使用されています。

静的アナライザーを使用して、最適化レベルが-O0より大きい場合は、ビルド設定に-Wuninitializedを有効にすることで、このことから自分を守ることができます。

一番の質問:1、2、3と記された行の最後の状態でfooを記述するための正しい用語は何ですか? 1 & 2のうち少なくとも1つは「初期化されていない」と呼ばれ、2 & 3のうちの1つは「初期化」されていますが、それはどのようなものですか。

  • 割り当てられているが、(そうでなければ使用することが安全ではない)
  • 初期化にObjCインスタンスまたはオブジェクトを初期化されていないにObjCインスタンス初期化されていない

    1. ARCの下
    +0

    I方法を見つけて、それからポストバックしてください。チェックするだけでアサーションも無効にしますか? – bacar

    +0

    @bacar:アサーションを無効にするには、 'NS_BLOCK_ASSERTIONS'コンパイラマクロを使用します。 –

    +0

    ポインタが自動的にnilになる状況はありますか?もしそうでなければ、これは私がメッセージに無関係に送信していた心配のほとんどを緩和します。 – bacar

    1

    あなたの当然の結果の質問への答え:#1の後

    、fooがを宣言したが、初期化されていないですされています。

    #2の後、fooはが割り当てられ、に割り当てられましたが、まだ未初期化です。

    #3の後、fooはで初期化されましたです。

    実際には、手順2と3を分ける必要はありません。つまり、コードはfoo = [[NSString alloc] init]である必要があります。その理由は、オブジェクトを割り当て、初期化したり、オブジェクトを不適切に初期化したりすることは「危険」であるためです。

    foo = [NSString alloc]これを行うだけでinitを呼び出すことを忘れた場合、初期化されていないため、fooを使用することは安全ではありません。同様に、[foo init](fooへの再割り当ての不足に気付く)も同様に安全ではありません。なぜなら、initは最初にallocによって割り当てられたものとは異なる初期化されたオブジェクトへの参照を返すことができるからです。

    +0

    この用語はどこかに書かれているのですか、本に記載されているのでしょうか? – bacar

    +0

    これは標準的なコンピュータ科学用語です。 – UIAdam

    +0

    OK :-)私はオブジェクトが構築されているか、そうでないC++/C#バックグラウンドから来ています - 間にはありません。 – bacar

    0

    ARC環境オブジェクトでは、オブジェクトは自動的にnilに設定されます。ただし、初期化中にオブジェクトに値を割り当てるのは、常に良い方法です。

    私はちょうど== nilでない通常のallocオブジェクトの後

    関連する問題