三種字符串的管理方式

NSString的三種實現方式

OC這個語言在不停的升級自己的內存管理,盡量的讓自己的

OC的字符串

問題引入

在學習字符串的過程中間會遇到一個因為OC語言更新造成的問題

例如:

int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = [NSString stringWithFormat:@"hello"];NSString* str2 = [NSString stringWithFormat:@"hello"];NSString* str3 = @"hello";NSLog(@"%d", str1 == str2);NSLog(@"%d", str2 == str3);}return 0;
}

按照書上的老版本來說的話,我們這里應該輸出兩個0才對,因為一個第一個和第二個都是堆區創建的他們應該是不一樣的,但是結果卻出乎我們的意料,我們這里在堆區中創建的兩個字符串的指針地址是一樣的。結果輸出了1。下面我們就解決一下這個問題。

在這里插入圖片描述

我們這時候輸出一下這幾個字符串的類型,這里就出現了這個NSTaggedPointerString這個類型,這時候我們會感到困惑,為什么我們明明是一個NSString類型,但是為什么會有這幾種情況呢?這里涉及到一個類簇的問題,但是這里就簡單理解成我們在這個NSString這個大類下有三種小的類別來管理這個類型,從而讓字符串有一個更好的儲存方式來保障我們的內存使用。

在這里插入圖片描述

這時候,我們來正式介紹一下在OC中間有關字符串的幾種實現方式。

OC中字符串NSString有三種實現方式,分別為

__NSCFConstantString,

__NSCFString,

NSTaggedPointerString.

現在我們通過一段代碼來分析這三種字符串的差異

代碼示例

我們給出一段代碼來分析一下有關這三種字符串的內容:

int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = @"hello";NSString* str2 = [NSString stringWithFormat:@"helloworld"];NSString* str3 = [NSString stringWithFormat:@"神"];NSString* str4 = [NSString stringWithFormat:@"hello"];NSLog(@"%lu, %@", [str1 retainCount], [str1 class]);NSLog(@"%lu, %@", [str2 retainCount], [str2 class]);NSLog(@"%lu, %@", [str3 retainCount], [str3 class]);NSLog(@"%lu, %@", [str4 retainCount], [str4 class]);//輸出他的一個引用計數和一個類型}return 0;
}

這是這個的輸出結果:

在這里插入圖片描述

我們現在就了解一下這三種字符串

__NSCFConstantString類型
  • 這個字符串類型是在常量區創建的一個字符串
  • 這個字符串是一種編譯時的常量
  • 我們可以用@""stringWithString方式創建
  • 打印的retainCount的值是很大的,無法通過release方式去釋放,是一個單例模式
int main(int argc, const char * argv[]) {@autoreleasepool {NSString* str1 = @"hello";NSString* str2 = [NSString stringWithFormat:@"helloworld"];NSString* str3 = [NSString stringWithFormat:@"神"];NSString* str4 = [NSString stringWithFormat:@"hello"];NSLog(@"%lu, %@", [str1 retainCount], [str1 class]);//NSLog(@"%lu, %@", [str2 retainCount], [str2 class]);//NSLog(@"%lu, %@", [str3 retainCount], [str3 class]);//NSLog(@"%lu, %@", [str4 retainCount], [str4 class]);[str1 release];NSLog(@"%lu, %@", [str1 retainCount], [str1 class]);}return 0;
}

這里我們進行了一次release操作,按道理來說我們應該是把對他進行了一次釋放的,但是打印結果是

在這里插入圖片描述

這里發現我們無法對其進行釋放,所以我們可以認為他是一個單例。

__NSCFString

  • 這個字符串類型是一個在堆區創建的一個字符串
  • 這個字符串是在運行的時候創建的
  • 較長字符串會自動轉化成這個類型
  • 中文字符串也會自動轉成這個類型
    這是他的引用計數:
    在這里插入圖片描述

從引用計數可以看出他不是一個單例,可以被釋放。
借用一段學長的話來對于這個字符串類型進行一個講解:

即使兩個對象的內容相同,它們在堆上的內存地址也是不同的。每個對象都在獨立的內存空間中存儲,具有自己的地址。這意味著通過不同的對象引用訪問這兩個對象時,實際上訪問的是不同的內存地址。

NSTaggerPointerSring

這個字符串類型是最新的一個字符串類型,他也是在堆區創建的但是他可用用來存儲一下較短字符串,實現一個節約內存的效果,引用一段學長的話

TaggedPointer的意思是標簽指針,這是蘋果在 64 位環境下對 NSString,NSNumber
等對象做的一些優化。簡單來講可以理解為把指針指向的內容直接放在了指針變量的內存地址中,因為在 64 位環境下指針變量的大小達到了 8
位足以容納一些長度較小的內容。于是使用了標簽指針這種方式來優化數據的存儲方式。從他的引用計數可以看出,這貨也是一個釋放不掉的單例常量對象。在運行時根據實際情況創建。

這里是有關他的引用計數:
在這里插入圖片描述
從這里可以看出他是一個單例。
也是通過一個stringWithFormat方式,但是由于較短英文字符串,所以可以用地址來直接存儲較短英文字符串的數值,這是一個單例。

  • 是一個單例
  • 是在堆區創建的一個字符串
  • 可以將其當作一個偽對象,對象直接被存儲在指針的地址上面
  • 較短且在堆區創建的字符串會呈現出這個樣式(長度小于9)

總結

我們這里簡單介紹了三種字符串的實現方式,這里只是簡單的介紹了這三種字符串的格子的一個特點,沒有深入的去研究它的底層代碼,我們這里主要需要理解在不同的情況下,字符串的創建出的類別是不一樣的。

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

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

相關文章

C++核心編程類的總結封裝案例

C類的總結封裝案例 文章目錄 C類的總結封裝案例1.立方體類的封裝2.點與圓的關系的封裝3.總結 1.立方體類的封裝 在C中,我們可以定義一個立方體(Cube)類來封裝立方體的屬性和方法。立方體的屬性可能包括邊長(side length&#xff…

【redis】set和zset常用命令

set 無序集合類型 sadd 和 smembers SADD:將一個或者多個元素添加到set中。注意,重復的元素無法添加到set中。 語法:SADD key member [member] 把集合中的元素,叫做member,就像hash類型中,叫做field類似. 返回值表示本次操作,添加成功了幾個元素. 時間復…

網絡原理——http/https ---http(1)

T04BF 👋專欄: 算法|JAVA|MySQL|C語言 🫵 今天你敲代碼了嗎 網絡原理 HTTP/HTTPS HTTP,全稱為"超文本傳輸協議" HTTP 誕?與1991年. ?前已經發展為最主流使?的?種應?層協議. 實際上,HTTP最新已經發展到 3.0 但是當前行業中主要使用的HT…

概念解析 | 為什么SAR中的天線間隔需要是四分之一波長?

注1:本文系“概念解析”系列之一,致力于簡潔清晰地解釋、辨析復雜而專業的概念。本次辨析的概念是:為什么SAR中的天線間隔需要是四分之一波長 概念解析 | 為什么SAR中的天線間隔需要是四分之一波長? 在這篇文章中,我們將深入探討**合成孔徑雷達(SAR)**系統中,為什么天…

明日周刊-第12期

以前小時候最期待六一兒童節了,父母總會給你滿足一個愿望,也許是一件禮物也許是一次陪伴。然而這個世界上其實還有很多兒童過不上兒童節,比如某些地區的小孩子,他們更擔心的是能不能見到明天的太陽。 文章目錄 一周熱點航天探索火…

LeetCode-77. 組合【回溯】

LeetCode-77. 組合【回溯】 題目描述:解題思路一:回溯背誦版解題思路三:0 題目描述: 給定兩個整數 n 和 k,返回范圍 [1, n] 中所有可能的 k 個數的組合。 你可以按 任何順序 返回答案。 示例 1: 輸入&a…

Python怎么使用 SQLAlchemy 和model 查詢數據呢?

SQLAlchemy是一個流行的Python SQL工具包和對象關系映射器(ORM)。 假設正在使用 SQLAlchemy 并有一個模型 MyModel,使用這個模型以及 query 方法來查詢數據庫。 這里有一個基本的例子,說明如何使用 SQLAlchemy 的 query 方法和 wi…

算法-對列表元素劃分成兩個和值最大且相等的子列表

現有私募基金發行一支特殊基金產品,該基金認購人數上限不超過 30 人, 募集總金額不超過 3000W,每個投資人認購金額不定。該基金只能將募集到的錢用于投資兩支股票,且要求兩支股票投資金額必須相同,且每位投資人的錢只能…

0X JavaSE-- 集合框架【Collection(List、Set、Queue)、Map】

每一個集合類底層采用的數據結構不同,例如ArrayList集合底層采用了數組,LinkedList集合底層采用了雙向鏈表,HashMap集合底層采用了哈希表,TreeMap集合底層采用了紅黑樹。**集合中存儲的是引用。**即。集合中存放的是對象的地址&am…

springboot報錯:Failed to start bean ‘documentationPluginsBootstrapper‘

項目場景: springboot項目啟動時報錯 問題描述 具體報錯信息: 可能原因分析: 1、SpringFox的版本與Spring Boot的版本不兼容。解決這個問題,你可能需要檢查你正在使用的SpringFox和Spring Boot的版本,確保它們是兼容…

一千題,No.0037(組個最小數)

給定數字 0-9 各若干個。你可以以任意順序排列這些數字,但必須全部使用。目標是使得最后得到的數盡可能小(注意 0 不能做首位)。例如:給定兩個 0,兩個 1,三個 5,一個 8,我們得到的最…

[AIGC] 使用Flink SQL統計用戶年齡和興趣愛好

Apache Flink是一個具有強大計算能力、高吞吐量、低延遲的分布式計算框架,它支持批計算和流計算。Flink SQL是Flink ecosystem的一部分,是一種對結構化數據進行批和流處理的聲明式語言。本文以一個簡單的實例講解如何使用Flink SQL來統計用戶年齡和興趣愛…

C# 面向對象編程(一)——類 第三篇

總目錄 C# 語法總目錄 系列鏈接 C# 面向對象編程(一) 類 第一篇 C# 面向對象編程(一) 類 第二篇 C# 面向對象編程(一) 類 第三篇 C# 面向對象編程 一 ——類 第三篇 簡介面向對象編程類 第三篇9. 重載運算符10. 分部方法** nameof方法 **** GetType 方法和 typeof方…

【Intro】Heterogeneous Graph Attention Network(HAN)

論文鏈接:https://arxiv.org/pdf/1903.07293 Abstract 異構性和豐富的語義信息給面向異構圖的圖形神經網絡設計帶來了巨大的挑戰。 -> 一種基于分層注意的異構圖神經網絡,包括節點級注意和語義級注意。具體來說,節點級關注旨在學習節點…

GPT4o還沒用上?落后一個月!

文章目錄 一.Share官方網站:以一半的價格享受官網服務1.1 網址1.2 一些介紹和教學實戰:1.3 主界面(支持4o):1.4 GPTS(上千個工具箱任你選擇):1.5 快速的文件數據分析(以數學建模為例…

一次“yarn Couldn‘t find package“問題的排查

本文記錄一次使用yarn install 時報錯 Couldn’t find package xxxx 問題的排查。 問題描述 問題來自于筆者對一個前端項目進行debug時的yarn install 報錯信息,在一個可以明確代碼沒有問題的項目中,因為切換環境,重新執行yarn install,發現…

qt qcomboBox實現自動檢索功能 通過輸入匹配字符進行篩選

本人做了一個自定義控件SeepedSearch 用于快速檢索匹配的字符的下拉框 方便查找目標 直接上源碼 1. SpeedSerach.h #pragma once #include class QComboBox; class QCompleter; class SpeedSearch : public QWidget { Q_OBJECT public: explicit SpeedSearch(QWidget *paren…

web前端三大主流框架指的是什么

web前端三大主流框架是什么?前端開發師的崗位職責有哪些?這邊整理了相關內容供大家參考了解,請各位小伙伴隨小編一起查閱下面的內容。 web前端三大主流框架 web前端三大主流框架是Angular、React、Vue。 1.Angular Angular原名angularJS誕生…

如何用python做一個貪吃蛇程序?——潯川AI社(VIP)

1 游戲說明: 死亡條件:碰壁、吃自己! 狀態:只有吃了食物才會隨機生成其中一種狀態,分別是:穩如老狗、幸運光滑、衰神附體之一 狀態:穩如老狗:相對于上一次速度不變! 狀態:幸運光滑:相對于上一次速度變慢! 狀態:衰神附體:相對于上一次速度變快! 總體速率對比…

UnityAPI學習之Transform組件基本使用

目錄 Transform組件 訪問與獲取 Transform的位置和旋轉信息 Transform局部坐標和旋轉信息的獲取 Transform的縮放與正方向 縮放(Scale) 正方向 Transform相關的查找方法 銷毀游戲物體 Transform組件 訪問與獲取 現在創建一個容器放置GrisGO物…