天天看點

ARC下的單例及其應用

dispatch_once 建立單例模式:

單例模式確定一個類隻有一個執行個體,自行提供這個執行個體并向整個系統提供這個執行個體。

dispatch_once函數中的代碼塊隻會執行一次,而且是線程安全的。

//  ViewController.m
//  MyGizmoDemo
//
//  Created by yons on 15-3-3.
//  Copyright (c) 2015年 yons. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

/**
 步驟:
 1.一個靜态變量_inastance
 2.重寫allocWithZone, 在裡面用dispatch_once, 并調用super allocWithZone
 3.自定義一個sharedXX, 用來擷取單例. 在裡面也調用dispatch_once, 執行個體化_instance
 -----------可選------------
 4.如果要支援copy. 則(先遵守NSCopying協定)重寫copyWithZone, 直接傳回_instance即可.
 
 
 */
/**第1步: 存儲唯一執行個體*/
static ViewController *_instance;

/**第2步: 配置設定記憶體孔家時都會調用這個方法. 保證配置設定記憶體alloc時都相同*/
+(id)allocWithZone:(struct _NSZone *)zone{
    //調用dispatch_once保證在多線程中也隻被執行個體化一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    
    return _instance;
}

/**第3步: 保證init初始化時都相同*/
+(instancetype)sharedTool{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[ViewController alloc]init];
    });
    return _instance;
}

/**第4步: 保證copy時都相同*/
-(id)copyWithZone:(NSZone *)zone{
    return _instance;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //執行個體化一個類的幾種方法. 單例就是要保證執行個體化出來的類是同一個類
    //1.alloc init方法. 一般不這麼來調用單例.
    ViewController *v1 = [[ViewController alloc]init];
    ViewController *v2 = [[ViewController alloc]init];
    
    ViewController *v3 = [ViewController sharedTool];
    ViewController *v4 = [v3 copy];
    NSLog(@"%@/n",v1);
    NSLog(@"%@/n",v2);
    NSLog(@"%@/n",v3);
    NSLog(@"%@/n",v4);
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
           

使用dispatch_once的好處:

1.線程安全

2.很好的滿足靜态分析需求

3.自動引用計數(ARC)相容

4.減少了代碼量