书写一个严谨的单例

简介: 什么是单例?一个类只有一个实例(一个对象),而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源

前言

什么是单例?

一个类只有一个实例(一个对象),而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源

正题

在iOS开发中单例是很平常的模式,但是昨天去面试的时候被人问到了一个比较尴尬的问题。
平常在项目中我们书写的单例大概应该都是这个样子,现在.h文件中声明一个类方法

@implementation Singleton

+(instancetype)shareInstance;

@end

然后在.m中去实现这个方法

@implementation Singleton

static Singleton *instance = nil;

+(instancetype)shareInstance{
    static dispatch_once_t onceToken;
    dispath_once(&onceToken,^{
        instance = [[self alloc]init];
    });
    return instance;
}

但是,昨天有人问了这么一个问题,说一般的都知道这个类方法是创建单例的,假如我不知道,我直接走了[[self alloc]init]方法来创建这个对象。那是不是就不能保证这个对象类的唯一性了?
仔细想一下好像是这样,这也是我个人的问题。在写项目的时候没有注意到这么个问题。在当时那个是时候我是被难住了......
之后我就写了一个demo试了一下

单例
这时我们再看看控制台中打印出来的信息

single1和single2的地址是一样的,因为都是走了那个类方法,可是single3就不一样了,这个时候这个Singleton就不严谨了。

解决问题

之后我就去网上找了一下,网上真的有很多人已经写过这样的技术博客了。我就去试了试。
主要就是为了确保对象的唯一性,所以我们需要封锁用户通过alloc和init以及copy来构造对象的这条路。
在创建对象的时候主要分这么两步 alloc (申请内存)init(初始化)
1.我们在第一步alloc的会后就要对其进行拦截。当我们去调用alloc的时候,OC内部会调用allocWithZone这个方法去申请内存,我们去覆写这个方法,然后在这个方法中调用之前的类方法,返单例对象,这样就能达到我们的目的了。
2.拷贝对象也是一样的,覆写copyWithZone方法,然后在方法中去调用类方法,返回单例对象。(在覆写copyWithZone方法之前别忘记了签署NSCopying协议)

类方法中也有做些许改动

#import <Foundation/Foundation.h>

@interface Singleton : NSObject<NSCopying>

+(instancetype)sharedInstance;

@end
#import "Singleton.h"

@implementation Singleton

static Singleton *instance = nil;

+(instancetype)sharedInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,^{
//        instance = [[self alloc]init];
        instance = [[super allocWithZone:NULL]init];
    });
    return instance;
}
+(id)allocWithZone:(struct _NSZone *)zone{
    return [Singleton sharedInstance];
}
-(id)copyWithZone:(NSZone *)zone{
    return [Singleton sharedInstance];
}
@end

接下来我们再看看通过不同方式创建之后的地址是否相同


控制台的输出

声明

本人并不是一个技术大神,只是一个菜鸟而已,写这个文章也不是为了炫耀什么,只是记录一下自己工作中的问题&如何解决。

相关文章
|
4月前
|
人工智能 物联网 Serverless
阿里云函数计算部署 ComfyUI + Flux:5 分钟搭一个 AI 生图服务
本文介绍如何用阿里云函数计算(FC)一键部署ComfyUI+Flux模型,实现轻量、低成本AI生图:5分钟完成部署,预置模型与LoRA,按调用计费(低至0.02元/张),免运维、免GPU环境搭建,特别适合中小批量、间歇性使用场景。
|
5月前
|
JSON API 数据格式
🚀 RESTful API 接口规范详解:构建高效、可扩展的 Web 服务(附 Python 源码)
本文深度解析RESTful API核心设计原则(资源化、无状态、统一接口等),详解URL规范、HTTP方法语义、状态码使用、响应格式及版本管理,并附可直接运行的Flask实战代码,助你构建专业、可扩展的Web服务。
|
5月前
|
人工智能 弹性计算 JSON
Hermes Agent/OpenClaw 阿里云部署及飞书集成、权限配置+自动化场景指南
OpenClaw(原Clawdbot)作为2026年最热门的开源AI智能体,在最新v2026.2.12版本中实现了飞书通道的原生支持,无需额外开发Webhook或依赖第三方插件,即可与飞书生态深度打通,实现消息收发、日程创建、文档协作、群聊管理等全场景自动化。对于企业用户和团队而言,将OpenClaw部署在阿里云上并接入飞书,既能享受云端的高稳定性与低延迟,又能让AI助手无缝融入日常办公流程,大幅提升协作效率。
673 3
|
5月前
|
弹性计算 人工智能 测试技术
阿里云服务器0元试用攻略:新手必看!从申请到性能测试流程参考
阿里云服务器ECS免费试用机制为开发者、初创企业及个人用户提供了零风险的上云验证路径。个人用户可享300元、企业用户660元试用额度,覆盖多规格多地域配置。用户通过"先试用后购买"模式,可零成本验证业务构想、深度评估产品匹配度,并熟悉云端运维操作。试用需完成实名认证且为新用户,每个账号限一次。此外,阿里云还提供解决方案免费试用(含POC验证)及超30款AI产品、7000万tokens免费体验,搭配99元起的长期优惠套餐,构建了完善的"先试后买"上云生态。
|
传感器 边缘计算 运维
AR 虚实叠加技术在工业设备运维中的实现流程方案
AR技术通过虚实信息融合,实现工业设备参数可视化、故障立体化、操作直观化,提升运维效率与精度。结合物联网与数字孪生,打造智能运维新范式。
|
10月前
|
SQL 存储 Apache
三、Hive DDL数据库操作
Hive 中的数据库(Schema)是构建数据仓库的基础单位。这次我们来了解 Hive 中创建、查看、切换、修改与删除数据库的 DDL 操作语法与用法,涵盖 COMMENT、LOCATION、DBPROPERTIES 等常用参数,辅以丰富示例与练习,助你扎实掌握 Hive 数据库管理核心能力。
707 11
|
IDE 测试技术 项目管理
【新手必看】PyCharm2025 免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!
PyCharm是由JetBrains开发的Python集成开发环境(IDE),专为Python开发者设计,支持Web开发、调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试和版本控制等功能。它有专业版、教育版和社区版三个版本,其中社区版免费且适合个人和小型团队使用,包含基本的Python开发功能。安装PyCharm前需先安装Python解释器,并配置环境变量。通过简单的步骤即可在PyCharm中创建并运行Python项目,如输出“Hello World”。
【新手必看】PyCharm2025 免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!
|
Java Android开发 开发者
Android10 修改开发者选项中动画缩放默认值
Android10 修改开发者选项中动画缩放默认值
1047 0
|
Python
还不会免费将PDF转为Word?你可以试试这3种工具!
还不会免费将PDF转为Word?你可以试试这3种工具!
912 0

热门文章

最新文章