1. 程式人生 > >iOS 建立單例的方法 dispatch_once

iOS 建立單例的方法 dispatch_once

單例的運用場景是:一種類,該類只能例項化一個物件。

iOS 建立單例的方法有:dispatch_once

舉例如下

假如有個全域性的狀態類,該類的介面部分如下:

@interface GlobalState ()
@end

該類的實現:

@implementation GlobalState

+ (GlobalState *)state
{
  static GlobalState *state = nil;
  
  static dispatch_once_t once;
  dispatch_once(&once, ^{
    state = [[M2GlobalState alloc] init];
  });
  
  return state;
}

@end

任何時候訪問共享例項,需要做的僅是:
GlobalState* state = [GlobalState state];

該種方法的特點:

1 執行緒安全         2 很好滿足靜態分析器要求         3 和自動引用計數(ARC)相容 
        4 僅需要少量程式碼

該方法的作用就是執行且在整個程式的宣告週期中,僅執行一次 dispatch_once 當中的 block 物件。

有些需要在程式開頭初始化的動作,也可以放到 dispatch_once 當中來執行,保證其僅執行一次。

這個函式需要一個斷言來確定這個程式碼塊是否執行,這個斷言的指標要儲存起來。

對於在應用中建立一個初始化一個全域性的資料物件(單例模式),這個函式很有用。如果同時在多執行緒中呼叫它,這個函式將等待同步等待,直至該block呼叫結束。

這個斷言的指標必須要全域性化的儲存,或者放在靜態區內。使用存放在自動分配區域或者動態區域的斷言,dispatch_once執行的結果是不可預知的。

使用該方法要注意的地方

(1)獲取單例的方法為類方法

(2)用靜態指標指向單例

(3)引數 dispatch_once_t 也為靜態的,否則結果不可知。

以下是官方文件

dispatch_once

Executes a block object once and only once for the lifetime of an application.

Declaration

SWIFT

funcdispatch_once(_predicate

:UnsafeMutablePointer<dispatch_once_t>,
                 
_block:dispatch_block_t!)

OBJECTIVE-C

voiddispatch_once(dispatch_once_t*predicate,dispatch_block_tblock);

Parameters

predicate

A pointer to a dispatch_once_t structure that is used to test whether the block has completed or not.

block

The block object to execute once.

Discussion

This function is useful for initialization of global data (singletons) in an application. Always call this function before using or testing any variables that are initialized by the block.

If called simultaneously from multiple threads, this function waits synchronously until the block has completed.

The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.

Import Statement

import Dispatch

Availability

Available in iOS 4.0 and later.

dispatch_once_t

A predicate for use with the dispatch_once function.

Declaration

SWIFT

typealias dispatch_once_t = Int

OBJECTIVE-C

typedeflongdispatch_once_t;

Discussion

Variables of this type must have global or static scope. The result of using this type with automatic or dynamic allocation is undefined. Seedispatch_once for details.

Import Statement

import Dispatch

Availability

Available in iOS 4.0 and later.