首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 中 initialize 與單例模式的正確結合

     編輯:關於C語言

initialize 方法特性

  • 每個類別在第一次被使用前,系統會自動呼叫 + (void)initialize,且整個程式執行期間只會呼叫一次(子類別若未覆寫,會繼承父類別的 initialize,但仍只呼叫一次);
  • 子類別若實作自己的 initialize,父類別與子類別的 initialize 各自呼叫一次;
  • 跨類別建立實例(如在另一個 ViewController 中 alloc/init)不會重複觸發 initialize。

實驗驗證

// InitTest.m
+ (void)initialize {
    NSLog(@"InitTest initialize: %@", [self class]);
}
- (instancetype)init {
    self = [super init];
    if (self) NSLog(@"InitTest init");
    return self;
}

// 子類別 InitTestChild 未覆寫 initialize

// ViewController.m
InitTest *t1 = [[InitTest alloc] init];
InitTest *t2 = [[InitTest alloc] init];
InitTestChild *c = [[InitTestChild alloc] init];
// 輸出:
// InitTest initialize: InitTest
// InitTest init
// InitTest init
// InitTest initialize: InitTestChild
// InitTest init

利用 initialize 實現線程安全單例

static InitTest *sharedInstance = nil;

+ (void)initialize {
    if (sharedInstance == nil) {
        sharedInstance = [[self alloc] init];
    }
}

+ (instancetype)defaultManager {
    return sharedInstance;
}

優點:無需 dispatch_once,語法簡潔,天然線程安全(initialize 由 runtime 保證只執行一次)。

注意事項

  • 若單例需延遲初始化,仍建議使用 dispatch_once 配合 allocWithZone: 覆寫;
  • initialize 中不可執行耗時操作,以免阻塞主線程啟動。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved