Load() +initialize()

2033 ワード

Prepare
  • Loadメソッドは、クラスがruntimeにロードされると実行され、A:Compile Sourceの順序に従ってロードされるという2つの条件に基づいています.B:Categoryは一般クラスの後になります.C:継承関係のあるものは親を先にロードします.
  • //Father 
    @implementation Father 
    + (void)load {
        NSLog(@"=== father load");
    }
    
    + (void)initialize {
        NSLog(@"=== father initialize");
    }
    @end
    
    //Son
    @interface Son : Father
    @end
    @implementation Son 
    + (void)load {
        NSLog(@"=== Son load");
    }
    
    + (void)initialize {
        NSLog(@"=== Son initialize");
    }
    @end
    //Father Category
    @implementation Father (category)
    + (void)load {
        NSLog(@"=== father category load");
    }
    
    + (void)initialize {
        NSLog(@"=== father category initialize");
    }
    @end
    //Son category
    @implementation Son (category)
    + (void)load {
        NSLog(@"=== Son category load");
    }
    
    + (void)initialize {
        NSLog(@"=== Son category initialize");
    }
    @end
    
    //Compile Source Order
    Son.m
    Father.m
    Son+category.m
    Father+category.m
    
    //OutPut
     === father load
     === Son load
     === Son category load
     === father category load
    
  • Initializeクラスの最初の初期化時に発生し、以下の法則に従う(もちろんloadメソッドで「self Class」のようなメソッドを呼び出すと、まずinitializeが呼び出される.A:継承関係のある子クラスがInitializeを実現していない場合、親クラス、すなわち親クラスのInitializeが2回呼び出される可能性がある.
  • //Father
    @implementation Father 
    + (void)initialize {
        NSLog(@"=== father initialize");
    }
    @end
    //Son
    @interface Son : Father
    @end
    @implementation Son 
    //+ (void)initialize {
    //    NSLog(@"=== Son initialize");
    //}
    @end
    //AppDelegate.m
    [Son new]
    [Father new]
    
    //OutPut
    === father initialize
    === father initialize
    
    //Resolver
    + (void)initialize {
        if (self == [Father class]){
            NSLog(@"=== father initialize");
        }
    }
    

    B:CategoryもInitializeを書き換えると、override、つまり元のクラスのInitializeは呼び出されません.
    //          
    === father category initialize
    === Son category initialize
    

    適用シーン
  • load()は起動時間を増加させ、やりすぎることには適さず、一般的に簡単なランタイムメソッド交換に用いられる.
  • Initialize()は、グローバル変数または静的変数のロードを遅延させる必要があるだけです.