• 关于GCD中单例的实现,不仅仅是 dispatch_once(视图完整版)


    之前太过于年轻,总结的简单单例模式传送门: http://www.cnblogs.com/PSSSCode/p/5482419.html

    这篇博客主要讲的是GCD中的单例模式,大家肯定会想到dispatch_once这个函数,但是这篇博客不仅仅是dispatch_once的使用。

    1、单例模式简介(面试常考的。。。)

    • 单例模式的作用
      • 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
      • 从而方便地控制了实例个数,并节约系统资源
    • 单例模式的使用场合  
      • 系统  
        • UIApplication、NSUserDefaults、NSFileManager、NSNoticationCenter 
      • 自定义
        • 在某个应用程序中,共享一份资源(这份资源只需要创建初始化一次)
        • 网络计数器
        • 分享界面、登录界面、评论界面不登录会跳转到唯一界面登录界面(单例实现)
        • 点击跳转,控制器设置为单例,该控制器不会被销毁,依然存在内存中,返回再次回去,再点击进来,则会快速进入不会创建对应的新的控制器

    2、具体代码

    • 只需实现三个方法
      • 1、allocWithZone:       (alloc底层调用该方法)
      • 2、shareCar          (一种命名规范)
      • 3、copyWithZone      (对应实例变量 调用copy会调用该方法)

    默认情况

    添加单例情况

     1 @interface PSSCar() // <NSCopying>
     2 
     3 @end
     4 
     5 @implementation PSSCar
     6 
     7 static PSSCar *_car;
     8 
     9 + (instancetype)allocWithZone:(struct _NSZone *)zone
    10 {
    11     static dispatch_once_t onceToken;
    12     dispatch_once(&onceToken, ^{
    13         _car = [super allocWithZone:zone];
    14     });
    15     return _car;
    16 }
    17 
    18 + (instancetype)sharedCar
    19 {
    20     static dispatch_once_t onceToken;
    21     dispatch_once(&onceToken, ^{
    22         _car = [[self alloc] init];
    23     });
    24     return _car;
    25 }
    26 
    27 - (id)copyWithZone:(NSZone *)zone
    28 {
    29     return _car;
    30 }

     

    3、封装代码

    当一个项目中多个类需要使用单例,则需要在对应类的.m文件中写以上的代码,并且代码几乎没有差别,所有可以将上面的代码封装成一个工具类,并在工具类中使用宏定义,减少代码冗余。

    // .h文件
    #define PSSSingletonH(name) + (instancetype)shared##name;
    
    // .m文件
    #define PSSSingletonM(name) 
    static id _instance; 
     
    + (instancetype)allocWithZone:(struct _NSZone *)zone 
    { 
        static dispatch_once_t onceToken; 
        dispatch_once(&onceToken, ^{ 
            _instance = [super allocWithZone:zone]; 
        }); 
        return _instance; 
    } 
     
    + (instancetype)shared##name 
    { 
        static dispatch_once_t onceToken; 
        dispatch_once(&onceToken, ^{ 
            _instance = [[self alloc] init]; 
        }); 
        return _instance; 
    } 
     
    - (id)copyWithZone:(NSZone *)zone 
    { 
        return _instance; 
    }

    在对应类的.h和.m中只需要调用宏定义重新命名的响应方法即可,同时将本类的类名传入,即可实现快速单例模式的实现与使用

  • 相关阅读:
    软考相关网站汇总
    教育界常用网站汇总
    vue实现选中li变色--小技巧
    vue前端路由的两种模式,hash与history的区别
    element中级联选择器动态加载数据 递归的思想(数据量过于庞大,后端不一次性把数据返回)
    关于echarts和高德地图使用的一些小细节
    Vue中的$set的使用 (为对象设置属性)
    高德地图根据地址获取经纬度
    vue强制刷新组件 (用keep-alive怎么都不生效,可能是因为这是组件,没涉及到路由),相当于每次重新初始化组件
    webpack
  • 原文地址:https://www.cnblogs.com/PSSSCode/p/5559865.html
Copyright © 2020-2023  润新知