• 玩转iOS开发:《iOS设计模式 — 单例模式》


    目录


    作者感言

    有一段时间没有发博客了, 刚好现在忙完项目的需求, 现在可以闲下来写写简书, 顺便自己给自己复习巩固一下知识, 不过我在这里又要吐槽一句, 项目中遇到了一个单例的问题, 让我感到非常的蛋疼, 写这个单例的人只是单纯了为了写单例而写单例, 没有想到会发生什么, 现在让我们一起来看看什么叫单例吧.

    最后:
    如果你有更好的建议或者对这篇文章有不满的地方, 请联系我, 我会参考你们的意见再进行修改, 联系我时, 请备注单例模式如果觉得好的话, 希望大家也可以打赏一下嘻嘻祝大家学习愉快谢谢

    Cain(罗家辉)
    联系方式: zhebushimengfei@qq.com
    腾讯QQ: 350116542


    简介

    UML

    这是一张单例的UML图, 非常简单明了的讲解单例类到底是怎么回事, 通常单例是用来作为管理中心, 或者是通知中心, 比如在iOS当中的NSNotificationCenter, [[UIApplication sharedApplication] statusBarStyle], NSUserDefaults, [NSFileManager defaultManager]等等都是单例, 单例类有几个特征.

    • 系统当中只有一个实例
    • 易于外界访问
    • 防止子类继承
    • 共享信息

    准备工作

    首先, 我们先来建一个WorkSpace, 这样子方便我们以后多添加工程, 因为单例模式只是我们的开始.

    1


    添加单例工程

    创建完WorkingSpace之后, 我们就来添加SingletonPattern(单例)的工程

    2

    3


    创建单例类

    现在我们来创建一个叫UserInfoManager单例类

    4

    声明一个类方法用于外界访问

    5

    #import <Foundation/Foundation.h>
    
    @interface UserInfoManagerCenter : NSObject
    
    + (instancetype)managerCenter;
    
    @end
    

    接下来我们去实现这个类方法就好了

    6

    #import "UserInfoManagerCenter.h"
    
    static UserInfoManagerCenter *managerCenter = nil;
    
    @implementation UserInfoManagerCenter
    
    + (instancetype)managerCenter {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            managerCenter = [[UserInfoManagerCenter alloc] init];
        });
            
        return managerCenter;
    }
    

    看起来, 我们好像搞定了整个单例模式了, 下面让我们来试试效果.

    7

    #import "ViewController.h"
    #import "UserInfoManagerCenter.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UserInfoManagerCenter *infoManagerCenter = [UserInfoManagerCenter managerCenter];
        UserInfoManagerCenter *managerCenter = [UserInfoManagerCenter managerCenter];
    
        NSLog(@"%@", infoManagerCenter);
        NSLog(@"%@", managerCenter);
    }
    
    @end
    

    打印出来的效果好像是只有一个, 但实际上并不是的, 我们再来看看

    8

    #import "ViewController.h"
    #import "UserInfoManagerCenter.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UserInfoManagerCenter *infoManagerCenter = [UserInfoManagerCenter managerCenter];
        UserInfoManagerCenter *managerCenter = [UserInfoManagerCenter managerCenter];
    
        UserInfoManagerCenter *userInfoManagerCenter = [[UserInfoManagerCenter alloc] init];
    
        NSLog(@"%@", infoManagerCenter);
        NSLog(@"%@", managerCenter);
        NSLog(@"%@", userInfoManagerCenter);
    }
    
    @end
    

    发现这个类还是可以初始化的, 并且是另外开辟了内存空间来存储的, 这就很尴尬了, 说好的只有一个实例呢???

    添加唯一单例判断

    我在这里说一句, 施主莫怕, 等贫僧跳大, 继续回到单例类当中, 添加几个判断就好了

    9

    #import "UserInfoManagerCenter.h"
    
    static UserInfoManagerCenter *managerCenter = nil;
    
    @implementation UserInfoManagerCenter
    
    + (instancetype)managerCenter {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            managerCenter = (UserInfoManagerCenter *)@"UserInfoManagerCenter";
            managerCenter = [[UserInfoManagerCenter alloc] init];
        });
        
        NSString *classString = NSStringFromClass([self class]);
        
        if ([classString isEqualToString:@"UserInfoManagerCenter"] == NO) {
            NSParameterAssert(nil);
        }
        
        return managerCenter;
    }
    
    - (instancetype)init {
        
        NSString *userInfomanagerCenter = (NSString *)managerCenter;
        
        if ([userInfomanagerCenter isKindOfClass:[NSString class]] && [userInfomanagerCenter isEqualToString:@"UserInfoManagerCenter"]) {
            
            if (self = [super init]) {
                // 这里直接什么都不做操作
            }
            
            return self;
        }
        
        return nil;
    }
    
    @end
    

    口说无凭, 我们来看看运行效果

    10

    这下子, 可以说明是只有一个实例了吧, 下面再来看看子类是否能继承

    11

    #import "ViewController.h"
    #import "UserInfoManagerCenter.h"
    #import "SubUserInfoManagerCenter.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UserInfoManagerCenter *infoManagerCenter = [UserInfoManagerCenter managerCenter];
        UserInfoManagerCenter *managerCenter = [UserInfoManagerCenter managerCenter];
    
        UserInfoManagerCenter *userInfoManagerCenter = [[UserInfoManagerCenter alloc] init];
        
        SubUserInfoManagerCenter *subUserInfoManagerCenter = [SubUserInfoManagerCenter managerCenter];
    
        NSLog(@"%@", infoManagerCenter);
        NSLog(@"%@", managerCenter);
        NSLog(@"%@", userInfoManagerCenter);
        NSLog(@"%@", subUserInfoManagerCenter);
    }
    
    @end
    

    12


    好了, 现在单例所需的

    • 易于外界访问
    • 系统当中只有一个实例
    • 防止子类继承

    我们都搞定, 酱紫我们就完成了一个单例类的创建啦


    工程地址:
    https://github.com/CainRun/DesignPattern/tree/master/SingletonPattern

  • 相关阅读:
    97. Interleaving String
    96. Unique Binary Search Trees
    95. Unique Binary Search Trees II
    94. Binary Tree Inorder Traversal
    odoo many2many字段 指定打开的form视图
    docker sentry 配置文件位置
    postgres 计算时差
    postgres 字符操作补位,字符切割
    postgres判断字符串是否为时间,数字
    odoo fields_view_get
  • 原文地址:https://www.cnblogs.com/iOSCain/p/5717043.html
Copyright © 2020-2023  润新知