iOS - + initialize 與 +load

1、+ initialize 方法和+load 調用時機

  • 首先說一下 + initialize 方法:蘋果官方對這個方法有這樣的一段描述:這個方法會在 第一次初始化這個類以前 被調用,咱們用它來初始化靜態變量。ios


    • load 方法會在加載類的時候就被調用,也就是 ios 應用啓動的時候,就會加載全部的類,就會調用每一個類的 + load 方法。框架

  • 以後咱們結合代碼來探究一下 + initialize 與 + load 兩個方法的調用時機,首先是 + load函數

    #pragram ---main函數中的代碼---#import <UIKit/UIKit.h>#import "AppDelegate.h"int main(int argc, char * argv[]) {  NSLog(@"%s",__func__);  @autoreleasepool {      return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
      }
    }#pragram ---基於NSObject的Person類---#import "Person.h"@implementation Person+ (void)load{  NSLog(@"%s",__func__);
    }
    + (void)initialize{
      [super initialize];  NSLog(@"%s %@",__func__,[self class]);
    }
    - (instancetype)init{  if (self = [super init]) {      NSLog(@"%s",__func__);
      }  return self;
    }@end#pragram ---基於Person的Son類---#import "Girl.h"@implementation Girl+ (void)load{  NSLog(@"%s ",__func__);
    }
    + (void)initialize{
      [super initialize];  NSLog(@"%s ",__func__);
    }
    - (instancetype)init{  if (self = [super init]) {      NSLog(@"%s",__func__);
      }  return self;
    }@end

    運行程序,咱們看一下輸出日誌:spa

    2015-10-27 15:21:07.545 initialize[11637:334237] +[Person load]2015-10-27 15:21:07.546 initialize[11637:334237] +[Girl load] 
    2015-10-27 15:21:07.546 initialize[11637:334237] main

    這說明在我並無對類作任何操做的狀況下,+load 方法會被默認執行,而且是在 main 函數以前執行的。scala

  • 接下來咱們來查看一下 + initialize 方法,先在 ViewController 中建立 Person 和 Girl 對象:日誌

    #import "ViewController.h"#import "Person.h"#import "Son.h"#import "Girl.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {
      [super viewDidLoad];  Person * a = [Person new];  Person * b = [Person new];  Girl *c = [Girl new];  Girl *d = [Girl new];
    }@end

    下面咱們來看一下輸出日誌:code

    2015-10-27 15:33:56.195 initialize[11711:342410] +[Person load]2015-10-27 15:33:56.196 initialize[11711:342410] +[Girl load] 
    2015-10-27 15:33:56.197 initialize[11711:342410] main2015-10-27 15:33:56.259 initialize[11711:342410] +[Person initialize] Person2015-10-27 15:33:56.259 initialize[11711:342410] -[Person init]2015-10-27 15:33:56.259 initialize[11711:342410] -[Person init]2015-10-27 15:33:56.259 initialize[11711:342410] +[Girl initialize] 
    2015-10-27 15:33:56.260 initialize[11711:342410] -[Girl init]2015-10-27 15:33:56.260 initialize[11711:342410] -[Girl init]

    經過這個實驗咱們能夠肯定兩點:對象

    • + initialize 方法相似一個懶加載,若是沒有使用這個類,那麼系統默認不會去調用這個方法,且默認只加載一次;繼承

    • + initialize 的調用發生在 +init 方法以前。it

  • 接下來再探究一下 + initialize 在父類與子類之間的關係,建立一個繼承自 Person 類的 Son類:

    #pragram ---ViewController 中的代碼---#import "ViewController.h"#import "Person.h"#import "Son.h"#import "Girl.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {
      [super viewDidLoad];
      Person * a = [Person new];
      Person * b = [Person new];
      Son*z = [Son new];
    }@end

    看一下輸出日誌:

    2015-10-27 15:44:55.762 initialize[12024:351576] +[Person load]2015-10-27 15:44:55.764 initialize[12024:351576] +[Son load]2015-10-27 15:44:55.764 initialize[12024:351576] +[Girl load] 
    2015-10-27 15:44:55.764 initialize[12024:351576] main2015-10-27 15:44:55.825 initialize[12024:351576] +[Person initialize] Person2015-10-27 15:44:55.825 initialize[12024:351576] -[Person init]2015-10-27 15:44:55.825 initialize[12024:351576] -[Person init]2015-10-27 15:44:55.826 initialize[12024:351576] +[Person initialize] Son2015-10-27 15:44:55.826 initialize[12024:351576] -[Person init]

    咱們會發現 Person 類的 + initialize 方法又被調用了,可是查看一下是子類 Son 調用的,也就是建立子類的時候,子類會去調用父類的 + initialize 方法。


2、總結

  • 若是你實現了 + load 方法,那麼當類被加載時它會自動被調用。這個調用很是早。若是你實現了一個應用或框架的 + load,而且你的應用連接到這個框架上了,那麼 + load 會在 main() 函數以前被調用。若是你在一個可加載的 bundle 中實現了 + load,那麼它會在 bundle 加載的過程當中被調用。

  • + initialize 方法的調用看起來會更合理,一般在它裏面寫代碼比在 + load 裏寫更好。+ initialize 頗有趣,由於它是懶調用的,也有可能徹底不被調用。類第一次被加載時,

  • + initialize 不會被調用。類接收消息時,運行時會先檢查 + initialize 有沒有被調用過。若是沒有,會在消息被處理前調用。

相關文章
相關標籤/搜索