zoukankan      html  css  js  c++  java
  • IOS设计模式——单例模式

    单例模式是23种设计模式中较容易实现的设计模式之一,目的是为了在程序运行时只产生一个对象,应用场景主要是1、类只能有一个实例,而且必须从一个为人熟知的访问点对其访问。2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。3、主要应用于工具类和调用次数比较多的类。我们这里只介绍在ARC模式下的单例模式,下面给出两种最典型的OC语言单例模式的代码:

    一、不使用GCD的单例模式

    头文件

     1 //
     2 //  DataTool.h
     3 //  02-单例模式
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 @interface DataTool : NSObject
    12 + (instancetype)sharedDataTool;
    13 @end

    实现文件

     1 //
     2 //  DataTool.m
     3 //  02-单例模式
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 #import "DataTool.h"
    10 
    11 @implementation DataTool
    12 static id _instance;
    13 
    14 /**
    15  *  alloc方法内部会调用这个方法
    16  */
    17 + (id)allocWithZone:(struct _NSZone *)zone
    18 {
    19     if (_instance == nil) { // 防止频繁加锁
    20         @synchronized(self) {
    21             if (_instance == nil) { // 防止创建多次
    22                 _instance = [super allocWithZone:zone];
    23             }
    24         }
    25     }
    26     return _instance;
    27 }
    28 
    29 + (instancetype)sharedDataTool
    30 {
    31     if (_instance == nil) { // 防止频繁加锁
    32         @synchronized(self) {
    33             if (_instance == nil) { // 防止创建多次
    34                 _instance = [[self alloc] init];
    35             }
    36         }
    37     }
    38     return _instance;
    39 }
    40 
    41 - (id)copyWithZone:(NSZone *)zone
    42 {
    43     return _instance;
    44 }
    45 @end

    二、使用GCD的单例模式

    引入GCD后我们将不再担心多线程的问题,也不用在代码中显式的为生成对象代码段上锁

    头文件

     1 //
     2 //  GCDDataTool.h
     3 //  02-单例模式
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 
    11 @interface GCDDataTool : NSObject
    12 + (instancetype)sharedGCDDataTool;
    13 @end

    实现文件

     1 //
     2 //  GCDDataTool.m
     3 //  02-单例模式
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 #import "GCDDataTool.h"
    10 
    11 @implementation GCDDataTool
    12 static id _instace;
    13 
    14 + (id)allocWithZone:(struct _NSZone *)zone
    15 {
    16     static dispatch_once_t onceToken;
    17     dispatch_once(&onceToken, ^{
    18         _instace = [super allocWithZone:zone];
    19     });
    20     return _instace;
    21 }
    22 
    23 + (instancetype)sharedGCDDataTool
    24 {
    25     static dispatch_once_t onceToken;
    26     dispatch_once(&onceToken, ^{
    27         _instace = [[self alloc] init];
    28     });
    29     return _instace;
    30 }
    31 
    32 - (id)copyWithZone:(NSZone *)zone
    33 {
    34     return _instace;
    35 }
    36 
    37 @end

    以上是单例模式最常见的实现的两种方式,因为代码比较成型,所以我们可以简化一下。

     1 // .h文件
     2 #define SingletonH(name) + (instancetype)shared##name;
     3 
     4 // .m文件
     5 #if __has_feature(objc_arc)
     6 
     7 #define SingletonM(name) 
     8 static id _instace; 
     9 
    10 + (id)allocWithZone:(struct _NSZone *)zone 
    11 { 
    12 static dispatch_once_t onceToken; 
    13 dispatch_once(&onceToken, ^{ 
    14 _instace = [super allocWithZone:zone]; 
    15 }); 
    16 return _instace; 
    17 } 
    18 
    19 + (instancetype)shared##name 
    20 { 
    21 static dispatch_once_t onceToken; 
    22 dispatch_once(&onceToken, ^{ 
    23 _instace = [[self alloc] init]; 
    24 }); 
    25 return _instace; 
    26 } 
    27 
    28 - (id)copyWithZone:(NSZone *)zone 
    29 { 
    30 return _instace; 
    31 }
    32 
    33 #else
    34 
    35 #define SingletonM(name) 
    36 static id _instace; 
    37 
    38 + (id)allocWithZone:(struct _NSZone *)zone 
    39 { 
    40 static dispatch_once_t onceToken; 
    41 dispatch_once(&onceToken, ^{ 
    42 _instace = [super allocWithZone:zone]; 
    43 }); 
    44 return _instace; 
    45 } 
    46 
    47 + (instancetype)shared##name 
    48 { 
    49 static dispatch_once_t onceToken; 
    50 dispatch_once(&onceToken, ^{ 
    51 _instace = [[self alloc] init]; 
    52 }); 
    53 return _instace; 
    54 } 
    55 
    56 - (id)copyWithZone:(NSZone *)zone 
    57 { 
    58 return _instace; 
    59 } 
    60 
    61 - (oneway void)release { } 
    62 - (id)retain { return self; } 
    63 - (NSUInteger)retainCount { return 1;} 
    64 - (id)autorelease { return self;}
    65 
    66 #endif

    调用示例

    头文件

     1 //
     2 //  SDataTool.h
     3 //  02-单例模式
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 #import <Foundation/Foundation.h>
    10 #import "Singleton.h"
    11 
    12 @interface SDataTool : NSObject
    13 SingletonH(SDataTool);
    14 
    15 @end

    实现文件

     1 //
     2 //  SDataTool.m
     3 //  02-单例模式
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 #import "SDataTool.h"
    10 
    11 @implementation SDataTool
    12 SingletonM(SDataTool);
    13 
    14 @end

    注:我们也可以把引用写在.pch文件中

    例如

     1 //
     2 //  PrefixHeader.pch
     3 //  03——单例模式IOS
     4 //
     5 //  Created by zhangjing on 15/7/5.
     6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
     7 //
     8 
     9 
    10 #ifdef __OBJC__//如果是OC语言文件
    11 #import "Singleton.h"
    12 #endif

    这样在其他OC语言文件中就不用特意引用了

  • 相关阅读:
    计算几何——交点、面积的计算
    计算几何——认识基本object:点、线、面 。
    图的拓扑排序——卡恩算法
    Manacher
    如何不改造 HBase 就能应对复杂查询场景
    如何做沟通
    大数据磁盘阵列技术
    Android系统架构开篇
    Apache Kylin 原理介绍与新架构分享(Kylin On Parquet)
    遭遇突然提问慌了?掌握关键2点完美应对zz
  • 原文地址:https://www.cnblogs.com/zhangjingyangjinjin/p/4623042.html
Copyright © 2011-2022 走看看