OCのグローバル変数、静的グローバル変数、定数、静的ローカル変数

4628 ワード

作成者:Love@YRリンク:http://blog.csdn.net/jingqiu880905/article/details/51997126 オリジナルを尊重してください.ありがとうございます.
まず、ヘッダファイルは.hファイル、ソースファイルは.mファイルを指します.
externは、変数または関数の前に配置して、変数または関数の定義が別のファイルにあることを示し、コンパイラがこの変数または関数に遭遇したときに、他のモジュールで定義を探すようにプロンプトします.また、externはリンク指定にも使用できます
extern int aは宣言であり、直接int aまたはint a=10またはextern int a=10は定義を指す.宣言は複数回可能で、定義は1回のみです.複数回定義されているのは同じ変数ではありません.
グローバル変数とは、@implement(@interface)および@end以外の変数を定義します.グローバル変数、すなわち外部変数.
次に、A.h A.mとB.h B.mの4つのファイルがあると仮定します.
  • A.mにグローバル変数int i=1を定義し、B.mに直接アクセスする.Aのいずれの方法でもiにアクセスできますが、Bの方法でiにアクセスする場合はプリコンパイルが通らず、use of undeclared identifier_に報告します.iエラー
  • A.mでグローバル変数int i=1を定義し、B.mでextern int iを定義します.Aのいずれの方法でもiにアクセスでき,Bの方法はiに対しても読み書き可能である.同じi
  • を使っています
  • A.mで静的グローバル変数static int i=1を定義し、B.mで直接アクセスします.Aのいずれの方法でもiにアクセスできますが、Bの方法でiにアクセスする場合はプリコンパイルが通らず、use of undeclared identifier_に報告します.iエラー
  • A.mに静的グローバル変数static int i=1を定義し、B.mにextern int iを定義する.Aのいずれの方法でもiにアクセスできますが、Bの方法でiにアクセスする場合はコンパイルが通らず、Undefined symbols iエラー
  • を報告します.
  • 静的グローバル変数static int i=200をA.mとB.mでそれぞれ定義する.static int i =300; 互いに影響を及ぼさず、同名で異なる記憶位置のiが2つあり、各ソースファイルのメソッドはそれぞれのソースファイルのiにアクセスする.
  • 静的グローバル変数static int i=200をA.mとB.mでそれぞれ定義する.およびグローバル変数int i=300;依然として互いに影響しない.もし私がAの中でextern int iになったら、Aの中の方法がアクセスしたiは依然として200で、Bの中のi
  • ではありません.
  • A.mとB.mでグローバル変数int i=200をそれぞれ定義する.およびint i=300;コンパイルが失敗した場合、duplicate symbolに報告します.iエラーは同様にA.mとB.mでグローバル定数const int i=200をそれぞれ定義する.グローバル変数int i=300と同様の上の7つをコンパイルしてもグローバル定数には適用されません.const int i = 11;static const int i=1とは異なり、constを付けずに書くだけで、constを付けて読むだけです.
  • A.hにグローバル変数extern int iを宣言する.A.mでグローバル変数int i=1を定義します.他のソースファイルでimport"A.h"を使用すると、Aで定義されたi
  • にアクセスできます.
    結論:非静的グローバル変数はグローバル役割ドメインを有する.1つのソースファイルで定義するだけで、すべてのソースファイルに作用します.グローバル変数定義を含まない他のソースファイルはexternで参照できます.(第1、2条に対応)
    静的グローバル変数の役割ドメインは、そのソースファイル内にのみ存在し、他のソースファイルで使用または変更できないため、他のソースファイルが同じ変数名を使用し、互いに独立することを心配する必要はありません.(第3,4,5条に対応)
    グローバル変数とローカル変数が重複している場合、ローカル変数の役割ドメイン内では、グローバル変数はブロックされて機能しません.(第6条に対応)
    グローバル変数は繰り返し定義できず、複数回宣言できる(第7条に対応)
    一般的に.hファイルにグローバル変数を定義しないでください.このように.hがimportされると、.hに相当するコードがコピーされ、複数回定義される場合があります.非staticの直接コンパイルエラーduplicate symbolの場合.staticの場合、このソースファイルに作用する静的グローバル変数は、複数のソースファイルimportで生成されます.(効果は第5条と同じ)
    次に、静的ローカル変数について説明します.(非静的)グローバル変数の役割ドメインはソースプログラム全体であり、静的グローバル変数の役割ドメインはそのソースファイルを定義し、静的ローカル変数の役割ドメインはその方法を定義します.
    以上の3つはいずれも静的データストレージ領域に割り当てられ、プログラムの実行開始時に1回のみ初期化され(クラスがインスタンス化されてから初期化されたわけではない)、プログラムの実行中は常に存在し、自動的にデフォルト値に割り当てられます.すべてコンパイル時に初期化されました.次回の使用時には元の付与値も保存できます
    したがって、上記の3つは、ストレージの場所とライフサイクルが同じで、役割ドメインが異なります.staticキーワードは、コンパイラ自身が変数の役割ドメインの範囲内でしか表示されないことを通知します.
    だから一つの方法にstatic int i=9という文があるとします.この方法に至るたびにこのiが9に割り当てられるわけではないが,初期化するときは9であるだけで,実際にコンパイルした後にこの方法からこの言葉に相当するものが取り出された.
    静的ではない局所変数がスタックに格納され,方法が出ると解放される.次回の使用は新規初期化します
    最後に,@implementと@end以外のC関数の定義について述べる:C関数はクラスやオブジェクトに依存しない.役割ドメインは、定義されたソースファイルです.他のファイルはimportを呼び出す必要があります.参照先:http://bbs.itheima.com/thread-138029-1-1.html
    最後にOCのクラスメソッドについてお話しします.
    
      self.arr =[@[@"str1", @"str2"]mutableCopy];
        [FirstViewController anyClassMehodWithParam:self.arr];
        
        
    +(void)anyClassMehodWithParam:(NSMutableArray *)arr
    {
        variableStr =@"";//    variableStr,  
        [self.arr replaceObjectAtIndex:0 withObject:@"modifiedStr1"];//arr  ,  
        
        NSLog(@"arr is %@",arr);
        [arr replaceObjectAtIndex:0 withObject:@"modifiedStr1"];
        
        [self anyClassMethod];//   
       
        [self deallocReloadable];//    ,  
        FirstViewController *fv = [[self alloc]init];
        [fv deallocReloadable];
        
    	timeDuration=22;//    timeDuration
    	i = 33;//      i
    	static int i =6;
        NSLog(@"i = %d",i);//      i
    
    }
    

    上の例では、クラスメソッドではインスタンス変数instance variableクラスメソッドにアクセスできません.プロパティクラスメソッドにアクセスできません.インスタンスメソッドを直接呼び出すことはできません.
    クラスメソッドは、クラスメソッド(self)を直接呼び出すことができます.クラスメソッドは、グローバルおよび静的変数クラスメソッドに直接アクセスできます.オブジェクトを作成することでインスタンスメソッドにアクセスできます.
    1.スタック-コンパイラによって自動的に割り当てられて解放される2.スタック-一般的にプログラマによって割り当てられて解放され、プログラマが解放されない場合、プログラムの終了時にOSによって回収される可能性がある3.グローバル領域(静的領域)で、グローバル変数と静的変数の記憶はブロックに置かれ、初期化されたグローバル変数と静的変数はブロック領域に置かれ、初期化されていないグローバル変数と初期化されていない静的変数は、隣接する別の領域にあります.-プログラム終了解放4.もう一つの特別な定数を置く場所があります.-プログラム終了リリース
    グローバルメソッドまたは変数は、クラスに関係なくselfで呼び出すことはできないし、void add()のような直接呼び出しでadd()をクラス名で呼び出すこともできないため、.mファイルの@implementの前または@endの後に定義されたメソッドまたは変数が.hファイルの@interfaceの前または@endの後に宣言されたメソッドまたは変数メソッドの前に+/-がない.
    2018年10月25日補足:a.hでstatic CGFloat cellHeight=30;そして、あるb.mでこのa.hを参照すると、異なるcellHeight(複数回定義すると同じ変数ではない)が生成されます.b.mでcellHeightを60に再割り当てすると、a.mの値は変わらないことがわかります.だからstatic変数を.hに定義して.mで.hを参照しないでください!