• 玩转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

  • 相关阅读:
    电脑无法开机,用一个U盘先备份C盘部分重要文件并重装Win10系统的教程?
    如何用WINPE备份电脑系统;电脑备份 听语音
    如何使用ghost备份系统?
    编程之美初赛第一场 活动中心
    从拟物到简约 ------谈站点设计风格的变革
    算法之回溯思想
    【工业串口和网络软件通讯平台(SuperIO)教程】一.通讯机制
    为什么要使用CMake+VS编译OpenCV的源代码
    Json实现异步请求(提交评论)
    kendo AutoComplete实现多筛选条件
  • 原文地址:https://www.cnblogs.com/iOSCain/p/5717043.html
Copyright © 2020-2023  润新知