OC-單例模式

文章目錄

  • 單例模式
    • 定義
    • 特點
    • 使用原因
    • 缺點
    • 模式介紹
      • 懶漢模式
        • 同步鎖實現
        • dispatch_once
      • 餓漢模式
        • 實現
    • 總結
      • 懶漢模式
        • 優點
        • 缺點
      • 餓漢模式
        • 優點
        • 缺點

單例模式

定義

單例模式,簡單的說就是一個類始終只對應同一個對象,每次獲取這個類的對象獲得的都是同一個實例

如果一個類始終只能創建一個實例,那么這個類被稱為單例類。單例類只有一個全局的接口來訪問這個實例。當第一次載入的時候,他通常使用延遲加載的方創建唯一單例。在程序中一個單例只初始化一次,為了保證在使用中始終存在,單例類的存儲是在存儲器的全局區域,在編譯時分配內存,只要程序在運行單例就始終存在,占用內存。在APP結束運行后釋放這部分內存。但是在系統方法中,存在未知的自動釋放池,如果對一個對象進行自動釋放的話,可能進入未知的釋放池,出現內存問題。即為單例模式不能自動釋放的原因

特點

  1. 單例類是一個類,這個類創造出的對象是單例對象
  2. 單例對象使用類方法創建
  3. 單例一旦被創建出來,直到程序結束運行才會釋放
  4. 單例不用我們來管理內存,內存會隨著程序關閉而被釋放

使用原因

節省內存,防止一個實例被重復創建從而占用內存空間。

缺點

  • 全局狀態:可能導致全局狀態的存在,使得程序難以調試,一個地方修改容易導致很多地方發生變化
  • 難以拓展:單例模式的實例是固定的,難以拓展以支持多個實例,必須修改代碼,使單例類丟失單例的特性
  • 隱藏依賴關系:可能會隱藏單例類的依賴關系,代碼更加耦合。

模式介紹

懶漢模式

是一種常見的單例設計模式,其主要特點是在需要時在創建單例對象的實現,通過延遲對象的初始化來節省資源和提高性能。適用于訪問量較小的情況,使用時間來換取空間

同步鎖實現
#import "Person.h"@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {@synchronized (self) {if (!instance) {instance = [[super allocWithZone:NULL] init];}}return instance;
}
@end

這一段代碼提供了一個全局訪問點sharedInstace類方法提供給外部訪問這個單例,在方法內部通過添加了一個同步鎖,限制了同一時間只有一個線程訪問臨界區的代碼。但是這里如果instance已經存在是沒有必要進入鎖的,所以可以再加個判斷如下:

#import "Person.h"@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {if (!instance) {@synchronized (self) {if (!instance) {instance = [[super allocWithZone:NULL] init];}}}return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone {if (!instance) {@synchronized (self) {if (!instance) {instance = [super allocWithZone:zone];}}}return instance;
}- (id)copyWithZone:(NSZone *)zone {return self;
}- (id)mutableCopyWithZone:(NSZone *)zone {return self;
}
@end

對于allocWithZone的參數,傳什么其實都無所謂,分配的內存區域不會改變
內層if的作用:假設有兩個線程A和B同時調用了sharedInstance,線程A先一步獲取鎖,進入代碼塊,此時線程B等待鎖釋放,當線程A初始化instance后釋放鎖,B獲得鎖,如果沒有內層if判斷,會再次創建實例,破壞了單例的唯一性

dispatch_once

通過一個靜態的dispatch_once變量來跟蹤代碼的執行狀態,第一次調用時原子操作發現標記狀態為未執行代碼塊,并原子性的將標記設為已執行,后續監測到標記為已執行,就會跳過該代碼塊。非常高效、沒有阻塞開銷

#import "Person.h"@implementation Person
static id instance = nil;
+ (instancetype)sharedInstance {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[super allocWithZone:NULL] init];});return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [super allocWithZone:zone];});return instance;
}- (id)copyWithZone:(NSZone *)zone {return self;
}- (id)mutableCopyWithZone:(NSZone *)zone {return self;
}
@end

我們打印出不同情況下的對象地址如下:
請添加圖片描述

餓漢模式

在類加載過程就完成這個單例的創建和初始化

實現
#import "Person.h"@implementation Person
static id instance = nil;+ (void)load {instance = [[super allocWithZone:NULL] init];
}+ (instancetype)sharedInstance {return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone {return instance;
}- (instancetype)init {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{NSLog(@"init一次");});return self;
}- (id)copyWithZone:(NSZone *)zone {return self;
}- (id)mutableCopyWithZone:(NSZone *)zone {return self;
}@end

總結

懶漢模式

優點
  1. 延遲加載,節省資源,提高性能。
  2. 避免在程序啟動時就創造不必要的對象,造成額外開銷
  3. 可以通過加鎖實現線程安全
缺點
  1. 為實現線程安全使用鎖機制,可能會引起一些性能開銷

餓漢模式

優點
  1. 實現簡單,不需要考慮線程安全問題,實例在類加載時就已經創建了,所以不用考慮創建多個實例的風險
缺點
  1. 程序啟動時就加載創建實例,可能會浪費資源,引起性能問題
  2. 如果單例對象的創建需要建立在某些外部前提下,那么不適合餓漢模式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96273.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96273.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96273.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[論文閱讀] 算法 | 抗量子+緊湊!SM3-OTS:基于國產哈希算法的一次簽名新方案

抗量子緊湊!SM3-OTS:基于國產哈希算法的一次簽名新方案 論文信息信息類別具體內容論文原標題SM3-OTS: 基于國密算法SM3的緊湊型后量子一次簽名方案主要作者楊亞濤、殷方銳、陳亮宇、潘登研究機構1. 北京電子科技學院 電子與通信工程系(北京 1…

C語言-指針用法概述

目錄 1.指針基礎概念 2. 指針與數組 3. 指針作為函數參數 4. 動態內存分配 5. 指針的高級用法 6. 常見錯誤與注意事項 7. 指針數組 vs. 數組指針 8.總結與建議 本文主要作為指針用法的復習,會對指針的大致用法進行舉例和概述。 1.指針基礎概念 ?什…

Java調用Whisper和Vosk語音識別(ASR)模型,實現高效實時語音識別(附源碼)

簡介 語音識別(Automatic Speech Recognition, ASR)是將人類的語音信號自動轉換為對應文字的技術,它使計算機能夠“聽懂”人說的話,是人機語音交互的核心技術,廣泛應用于智能助手、語音輸入、客服系統等場景。 現在我…

第3周 機器學習課堂記錄

1.學習問題的分類有監督的學習分類回歸無監督學習聚類密度估計:確定輸入空間中的數據的分布可視化:把高位空間中的數據投影到二維或三維空間強化學習不給定最優輸出的示例,而是通過試錯發現最優輸出2.泛化versus過度擬合背景引入:…

消息隊列(MQ)高級特性深度剖析:詳解RabbitMQ與Kafka

一、引言:為什么需要關注高級特性? 在現代分布式系統架構中,消息隊列(Message Queue)已成為不可或缺的核心組件。初級使用消息隊列可能只需幾行代碼就能實現基本功能,但要真正發揮其在大規模生產環境中的威…

【GPT入門】第65課 vllm指定其他卡運行的方法,解決單卡CUDA不足的問題

【GPT入門】第65課 vllm指定其他卡運行的方法,解決單卡CUDA不足的問題1.原理說明:2.實踐1.原理 要將 vllm 部署在第二張 GPU 卡上(設備編號為 1),只需在命令前添加 CUDA_VISIBLE_DE…

Spring Boot Actuator自定義指標與監控實踐指南

Spring Boot Actuator自定義指標與監控實踐指南 本篇文章以生產環境實戰經驗為主線,結合某電商系統的業務場景,講解如何在Spring Boot Actuator中添加并暴露自定義指標,并使用Prometheus和Grafana進行完整的監控與告警配置。 一、業務場景描述…

Vue報錯<template v-for=“option in cardOptions“ :key=“option.value“>

在Vue項目中遇到報錯&#xff0c;原因是模板中使用了<template>標簽內的v-for指令&#xff0c;而當前Vue版本不支持此用法。解決方案是移除<template>標簽&#xff0c;直接在<el-option>上使用v-for。同時優化計算屬性cardOptions&#xff0c;使其能夠兼容歷…

人工智能學習:Transformer結構中的規范化層(層歸一化)

Transformer結構中的規范化層(層歸一化) 一、規范化層(層歸一化)介紹 概念 層歸一化(Layer Normalization) 是一種用于提高深度神經網絡訓練穩定性和加速收斂的技術,廣泛應用于現代深度學習模型中,尤其是在Transformer等序列建模網絡中。它通過對每一層的輸出進行歸一化…

盼之代售 最新版 decode__1174

聲明 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包內容、敏感網址、數據接口等均已做脫敏處理&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01; 逆向分析 部分python代碼 cp1 execj…

Transformer系列 | Pytorch復現Transformer

&#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 一、Transformer和Seq2Seq 在之前的博客中我們學習了Seq2Seq(深度學習系列 | Seq2Seq端到端翻譯模型)&#xff0c;知曉了Attention為RNN帶來的優點。那么有沒有…

【MySQL】常用SQL語句

介紹常用的DDL語句、DML語句基本語法分號結尾使用空格和縮進不區分大小寫--或#注釋單行內容 /*注釋多行內容*/DDL數據定義語句&#xff1a;定義數據庫、表、字段一、操作庫-- 創建庫create database db1;-- 創建庫是否存在&#xff0c;不存在則創建create database if not exi…

云手機就是虛擬機嗎?

云手機并非等同于虛擬機&#xff0c;盡管二者存在一定相似性&#xff0c;但有著諸多區別&#xff0c;以下從多個方面來分析&#xff1a;云手機是一種基于云計算技術&#xff0c;將云端服務器虛擬化為手機設備&#xff0c;用戶能通過網絡遠程操控的虛擬手機服務&#xff0c;它從…

準確--Nginx 1.28.0 安裝與配置流程

Nginx 1.28.0 安裝與配置流程 1. 下載與解壓 cd ~ wget http://nginx.org/download/nginx-1.28.0.tar.gz tar -zxvf nginx-1.28.0.tar.gz cd nginx-1.28.02. 配置編譯參數 ./configure \--prefix/home/ynnewweb/nginx \--with-http_ssl_module \--with-http_gzip_static_module…

無標記點動捕新范式:Xsens系統助力人形機器人實現毫米級動作復刻

Xsen搭載Manus數據手套在機器人操作與機器學習中的應用當前&#xff0c;人形機器人正加速向工業裝配、家庭陪護、倉儲物流等場景滲透&#xff0c;而 “如何讓機器人的動作既符合人類運動規律&#xff0c;又能實現高精度執行” 成為制約其落地的核心瓶頸。Xsens 高精度全身動捕系…

mysql57超管root忘記密碼怎么辦

目錄 背景 1.首先停止數據庫 2.使用免密模式啟動 3.修改密碼 3.1刷新權限配置 3.2修改密碼 4.殺掉mysql 5.重新正常啟動mysql 6.查看mysql狀態 7.驗證 7.1首先服務器本地驗證 7.2遠程驗證 背景 數據庫密碼忘記了,急的抓耳撓腮,怎么也想不起來,于是就開始重置吧 1.…

RESTful API:@RequestParam與@PathVariable實戰對比

RequestParam vs PathVariable 在刪除和查找操作中的使用差異 在項目實戰中&#xff0c;選擇使用 RequestParam 還是 PathVariable 來接收ID參數&#xff0c;通常基于以下幾個考慮因素&#xff1a; 1. RESTful API 設計原則 查找操作使用 PathVariable GetMapping("/depts…

劇本殺小程序系統開發:開啟沉浸式社交娛樂新紀元

在當今數字化浪潮席卷的時代&#xff0c;社交娛樂方式正經歷著前所未有的變革。劇本殺&#xff0c;這一融合了角色扮演、推理懸疑與社交互動的線下娛樂項目&#xff0c;近年來迅速風靡全國&#xff0c;成為年輕人熱衷的社交新寵。而隨著移動互聯網的蓬勃發展&#xff0c;劇本殺…

中線安防保護器,也叫終端電氣綜合治理保護設備為現代生活筑起安全防線

中線安防保護器&#xff08;Neutral Line Protection Device&#xff0c;簡稱NLPD&#xff09;是一種專門用于監測和保護電力系統中性線的安全裝置。中線安防保護器的基本原理為:通過電流檢測環節采集系統中性線上過電流信息&#xff0c; 經控制器快速計算并提取各次諧波電流的…

Spring Cloud Alibaba快速入門02-Nacos配置中心(下)

文章目錄前言配置中心 - 數據隔離示例1.先創建命名空間2.創建配置3.克隆配置4.動態切換環境5.yml多文檔模式spring.profiles.activedevspring.profiles.activetest總結前言 上一章簡單了解了Nacos配置中心的基本用法&#xff0c;這一章將開始Nacos配置中心的實戰案例。 配置中…