【iOS】MRC下的单例模式批量创建单例

news2024/11/15 15:30:21

单例模式的介绍和ARC下的单例请见这篇:【iOS】单例模式

目录

    • 关闭ARC环境
    • MRC下的单例
    • ARC下的单例
    • 批量创建单例
    • Demo


关闭ARC环境

首先关闭ARC环境,即打开MRC:

在这里插入图片描述
或是指定某特定目标文件为非ARC环境:

在这里插入图片描述
双击某个类文件,指定为ARC环境,输入-fobjc-arc,指定为MRC环境,输入-fno-objc-arc

MRC下的单例

MRC下,我们就需要手动释放资源,通过重写一些与资源创建与释放相关的方法,以保证单例对象的唯一。

SingletonByMRC.h

@interface SingletonByMRC : NSObject
+ (instancetype)sharedSingletonByMRC;
@end

SingletonByMRC.m

@implementation SingletonByMRC

static SingletonByMRC* instanceVariable = nil;

/*
 alloc方法内部会调用allocWithZone:
 参数zone时系统分配给App的内存
 */
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    if (!instanceVariable) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{  // 安全(这段代码只会被调用一次)
            instanceVariable = [super allocWithZone: zone];
        });
    }
    return instanceVariable;
}

- (oneway void)release {
    //  allocWithZone中使用了GCD命令创建对象的代码只执行一次(单例),如果被释放则无法再创建
    //  重写release方法,替换为空操作,防止instanceVariable被释放
}

//  重写retain方法
- (instancetype)retain {
    return self;
}

//  重写retainCount锁定引用计数
- (NSUInteger)retainCount {
    return 1;
}

//  重写init方法,防止单例所拥有的属性值被重置
//  让初始化的方法只能执行一次,自然属性值就没有机会被重置
- (instancetype)init {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instanceVariable = [super init];
    });
    return instanceVariable;
}

//  仿造系统的单例创建方式,提供类方法
+ (nonnull instancetype)sharedSingletonByMRC {
    // 由于我们已经重写了init方法保证了单例对象的唯一了,所以这里直接调用init方法即可。
    return [[self alloc] init];
}

@end


ARC下的单例

与MRC的主要区别就是不用再手动去释放资源了。

SingletonByARC.m

#import "SingletonByARC.h"

@implementation SingletonByARC

static SingletonByARC* insVar = nil;

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    if (!insVar) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            insVar = [super allocWithZone: zone];
        });
    }
    return insVar;
}

- (instancetype)init {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        insVar = [super init];
    });
    return insVar;
}

+ (instancetype)sharedInstance {
    return [[self alloc] init];
}

@end

批量创建单例

如果一个项目中需要多个单例,总不能把上面的代码一个一个复制粘贴再改改就完事了吧?那未免也太麻烦了。
我们可以利用快速且简单地创建单例。

首先先说下一些关于宏的知识:

  • 使用#define关键字来定义宏
  • 宏定义只能是单行的,不能换行

那现在来讨论下一些疑惑吧,你说宏只能单行,可是创建单例的代码可是有很多行呀!还有我们如何做到自定义类方法名(就是 sharedXXX )?我们来介绍下宏下的两个特殊符号:

符号作用
\用来转译换行符,即屏蔽换行符
##将两个相邻的标记(token)连接为一个单独的标记

简言之,就是\用于取消换行,##用于连接。

创建头文件Singleton.h存放头文件:

#define SingletonH(methodName) + (instancetype)shared##methodName;

#define SingletonM(methodName) \
static id _instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
    if (!_instance) { \
        static dispatch_once_t onceToken; \
        dispatch_once(&onceToken, ^{ \
            _instance = [super allocWithZone:zone]; \
        }); \
    } \
    return _instance; \
} \
\
- (instancetype)init { \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super init]; \
    }); \
    return _instance; \
} \
\
+ (instancetype)shared##methodName { \
    return [[self alloc] init]; \
}

SingletonH(methodName)为声明宏,SingletonM(methodName)为实现宏。在每一行后面加上(反斜杠)取消换行,使用##来拼接传入的方法名,需要注意的是:最后一行不能加反斜杠。

SingletonClass.h文件中直接声明shareSingleMethod方法:

#import "Singleton.h"

@interface SingletonClass : NSObject
SingletonH(SingleMethod);
@end

将方法名SingleMethod传入SingletonH();中就可以拼接为shareSingleMethod

SingletonClass.m直接实现创建单例类

#import "SingletonClass.h"

@implementation SingletonClass
SingletonM(SingleMethod);
@end

运行结果:

请添加图片描述

最终我们仅仅用了“两”行代码,成功创建出了一个单例类,这样是不是节省了大量多余冗杂的代码呢。

Demo

【Github】使用单例进行传值

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot整合WebSocket和Redis实现直播间在线人数统计功能

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

【PyTorch】PyTorch深度学习框架实战(二):torchrun

一、引言 PyTorch由facebook人工智能研究院研发,2017年1月被提出,是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的…

【React】vscode 中 React 自动补齐标签设置

1.打开设置 2.搜索 includeLanguages 3. 在Emmet 下,点击“添加项”,添加一项 javascript --> javascriptreact 4. 重启vs code

【SkyWalking】使用PostgreSQL做存储K8s部署

拉取镜像 docker pull apache/skywalking-ui:10.0.1 docker tag apache/skywalking-ui:10.0.1 xxx/xxx/skywalking-ui:10.0.1 docker push xxx/xxx/skywalking-ui:10.0.1docker pull apache/skywalking-oap-server:10.0.1 docker tag apache/skywalking-oap-server:10.0.1 xxx…

第一波因为AI失业的设计师

“学了很多年美术,画功不如AI输入词条几十秒就出的画” 200多年前,摄影技术刚诞生时,画家们也是眼睁睁看着照相机攻城略地,法国著名设计师保罗德拉罗也留下了那句经典的论断:“从今天起,绘画死亡了。”但历…

解锁俄罗斯市场:如何选择优质的俄罗斯云服务器

在当前云计算市场上,很多大型的云厂商并没有俄罗斯服务器的云节点,这给许多企业在拓展海外业务时带来了一定的困扰。然而,俄罗斯作为一个经济发展迅速的国家,其市场潜力不可忽视。因此,选择一台优质的俄罗斯云服务器成…

仪表板展示|DataEase看中国:2024年高考数据前瞻

背景介绍 2024年高考即将来临。根据教育部公布的数据,2024年全国高考报名人数为1342万人,相比2023年增加了51万人。高考报名人数的增加,既体现了我国基础教育的普及范围之广,也反映了社会对高等教育的重视和需求。 随着中央和各…

系统与软件工程软件测试文档

组织级软件测试文档结构图集 组织级测试过程文档集 组织级测试规格说明描述组织层面的测试信息,并且不依赖于项目。其在组织级测试过程中的典型事例包括: 测试方针:测试方针定义了组织内适用的软件测试的目的和原则,它定义了测试…

ElasticSearch教程(详解版)

本篇博客将向各位详细介绍elasticsearch,也算是对我最近学完elasticsearch的一个总结,对于如何在Kibana中使用DSL指令,本篇文章不会进行介绍,这里只会介绍在java中如何进行使用,保证你看完之后就会在项目中进行上手&am…

Java学习-JDBC(一)

JDBC 概念 JDBC(Java Database Connectivity)Java数据库连接JDBC提供了一组独立于任何数据库管理系统的APIJava提供接口规范,由各个数据库厂商提供接口的实现,厂商提供的实现类封装成jar文件,也就是我们俗称的数据库驱动jar包JDBC充分体现了…

IP SSL使用率增长有利于网络安全防护!

目录 IP的特殊性 IP证书的作用原理: 申请IP证书的基本条件: 申请IP SSL证书: 对于SSL证书来说,很多朋友应该并不陌生,目前SSL证书广泛应用在域名服务器上,所以大家最熟悉的证书类型可能就是单域名SSL证…

element-plus 的icon 图标的使用

element-plus的icon 已经独立出来了,需要单独安装 1. npm安装 icon包 npm install element-plus/icons-vue2.注册到全局组件中 同时注册到全局组件中,或者按需单独引入,这里只介绍全局引入。 import { createApp } from vue import { cre…

(UE4.26)UE4的FArchive序列化入门

前言 序列化(Serialize)和反序列化(UnSerialize)是程序领域常见的概念。对于这两个词汇我理解的是 序列化(Serialize): 变量值(int, float, string等基本类型, 或者Array,Map,或者更复杂的复合体)存储为一个文件(二进制流, 二进制文件, json, xml等格式…

使用 PAI-DSW x Free Prompt Editing图像编辑算法,开发个人AIGC绘图小助理

教程简述 在本教程中,您将学习在阿里云交互式建模平台PAI-DSW x Free Prompt Editing(CVPR2024中选论文算法)图像编辑算法,开发个人AIGC绘图小助理,实现文本驱动的图像编辑功能单卡即可完成AIGC图片风格变化、背景变化…

277 基于MATLAB GUI火灾检测系统

基于MATLAB GUI火灾检测系统,可以实现图片和视频的火苗检测。火焰识别的三个特征:1个颜色特征,2个几何特征颜色特征:HSV颜色空间下,对三个通道值进行阈值滤波,几何特征1:长宽比,几何…

k8s——pod控制器

一、pod控制器定义 Pod控制器,又称之为工作负载(workload),是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效&#xf…

NIST 电子病历中的疾病列表部分的认证

美国国家标准与技术研究院(National Institute of Standards and Technology,NIST)对电子病历的认证 分几个阶段,每个阶段又分门诊和住院,然后又分若干模块。下面是疾病列表的测试脚本。 170.302c_Problemlist Test …

(一)大数据基础练习题(66道选择题)

本文整理了大数据基础知识相关的练习题,共66道,适用于想巩固大数据基础的同学。来源:如荷学数据科学题库(技术专项-大数据)。 1) 2) 3) 4) 5) 6)…

高考分数查询结果自动推送至微信

又是一年高考时,祝各位学子金榜题名,天遂人愿! 在您阅读以下内容时,请注意:各省查分API接口可能不相同,本人仅就技术层面谈谈, 纯属无聊,因为实用意义不大,毕竟一年一次,…

【机器学习】XGBoost: 强化学习与梯度提升的杰作

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 XGBoost: 强化学习与梯度提升的杰作引言1. XGBoost概览1.1 什么是XGBoost&#…