此篇為針對Objective-c語言入門的基礎知識,為了能讓大家更清楚的理解,此整理中編寫了許多的代碼案例和部分截圖,如有錯誤之處,望指正,願與您相互交流學習,共同進步! "會飛的猴子_阿新" (同時還要向刀哥致敬) 本篇目標是: 理解記憶體五大區域及各自的職責 目錄結構 00.簡述 01. 分配和釋 ...
此篇為針對Objective-c語言入門的基礎知識,為了能讓大家更清楚的理解,此整理中編寫了許多的代碼案例和部分截圖,如有錯誤之處,望指正,願與您相互交流學習,共同進步!---"會飛的猴子_阿新" (同時還要向刀哥致敬)
本篇目標是: 理解記憶體五大區域及各自的職責
目錄結構
- 00.簡述
- 01. 分配和釋放(面試常被問到)
- 02.棧區和堆區
- 0.3 全局變數、靜態變數和常量
- 本篇主要學習目標回顧:
- 結束語
00.簡述
程式要想執行,第一步就需要 被載入到記憶體中
記憶體五大區域: 棧區,堆區,BSS段(靜態區),常量區(數據段),代碼段.
棧區
: 局部變數和方法實參堆區
:OC中使用new方法創建的對象,被創建對象的所有成員變數保存在堆區中.BSS段(也叫靜態區)
:
教科書
:未被初始化的全局變數和靜態變數.
Xcode8中
: 全局變數和靜態變數,不管有沒有被初始化,都存放在BSS段中.驗證見本篇中的案例.常量區(也叫數據段)
:
教科書: 存儲已經初始化的全局變數,靜態變數,常量.
xcode8: 存儲常量
代碼段
: 程式的代碼.
01. 分配和釋放(面試常被問到)
-
棧區
(stack [stæk]): 由編譯器自動分配釋放- 局部變數是保存在棧區的
- 方法調用的實參也是保存在棧區的
-
堆區
(heap [hiːp]): 由程式員分配釋放,若程式員不釋放,會出現記憶體泄漏- 賦值語句右側 使用 new 方法創建的對象
- 被創建對象的所有 成員變數
-
BSS 段
: 程式結束後由系統釋放 -
數據段
: 程式結束後由系統釋放 -
代碼段
:程式結束後由系統釋放程式 編譯鏈接 後的二進位可執行代碼
02.棧區和堆區
int main(int argc, const char * argv[]) {
// 局部變數是保存在棧區的
// 棧區變數出了作用域之後,就會被銷毀
NSInteger i = 10;
NSLog(@"%zd", i);
// 局部變數是保存在棧區的
// 賦值語句右側,使用 new 方法創建的對象是保存在堆區的
// xinge 變數中,記錄的是堆區的地址
// 在 OC 中,有一個記憶體管理機制,叫做 `ARC`,可以自動管理 OC 代碼創建對象的生命周期
// 因此,在開發 OC 程式的時候,程式員通常不需要考慮記憶體釋放的工作
LJXPerson *xinge = [LJXPerson new];
NSLog(@"%@", xinge);
return 0;
}
10
<LJXPerson: 0x100404b70>
2.1 棧區
棧區 (stack [stæk]) : 由編譯器自動分配釋放
2.1.1 棧區中的保存(棧區的職責/存儲的內容)
-
局部變數
-
方法實參
(eg:在main函數中,調用方法,方法中的實參)
2.1.2 棧區的特點
-
存儲空間有限
. iphone的棧區大小隻有512k
(預設) ,非常有限 -
連續性
. 棧區的地址是連續的
部分代碼:
#import <Foundation/Foundation.h>
#import "LJXPerson.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSInteger i = 10;
NSLog(@"i 的棧區地址是 %p", &i);
NSInteger j = 10;
NSLog(@"j 的棧區地址是 %p", &j);
// xiaoming 變數中,存儲的是 LJXPerson
對象的記憶體地址(堆區的記憶體地址)
LJXPerson *xinge = [LJXPerson new];
NSLog(@"xinge 的棧區地址是 %p", &xinge);
double height = 10;
NSLog(@"height 的棧區地址是 %p", &height);
.......
i 的棧區地址是 0x7fff5fbff768
j 的棧區地址是 0x7fff5fbff760
xinge 的棧區地址是 0x7fff5fbff758
height 的棧區地址是 0x7fff5fbff750
地址分配從大到小
. 棧區地址按照分配的順序,由大到小順序排列訪問速度快
.系統管理
. (棧區的記憶體由系統管理)
2.1.3 其他
如果在程式中調用方法,會開啟一個 " 棧幀 ".(這個棧幀可以理解為也是一塊連續的區域)
棧幀的地址與之前的局部變數的地址不是連續的棧幀中記錄實參地址,
以及方法內部的局部變數方法執行完畢後,棧幀銷毀(彈棧)
<<<這樣每次執行完畢後,都彈棧釋放記憶體,這樣就會始終保證棧區占用的記憶體不會特別大>>
so-課外話->我們在開發的時候,如果每個方法都寫的很短,同時每個方法聲明的變數都很少.
這樣做一定會節約記憶體
見圖知意
添加 "在一個函數/方法中"
即在一個函數/方法中最多可定義65536,--->因為"每次"執行完"一個"方法之後就會彈棧釋放記憶體
棧的概念: 後進先出/ 先進後出
見圖知意:
NSLog(@"NSInteger 變數占用的位元組數 %tu", sizeof(NSInteger));
NSLog(@"double 變數占用的位元組數 %tu", sizeof(double));
NSLog(@"xinge 變數占用的位元組數 %tu", sizeof(xinge));
// 提示:棧區中,只適合存儲非常小的數據
NSLog(@"在 iPhone 中,最多可以在一個函數/方法中定義 %zd 個局部變數", 512 * 1024 / 8);
// 測試方法調用時,實參在棧區的存儲情況
[xinge sumWithNum1:i andNum2:j];
總結: 調用方法時棧區的工作原理
* 開啟棧幀
* 保存實參
* 保存局部變數
* 方法完成後彈棧,銷毀棧幀,釋放空間
2.2 堆區
堆區 (heap [hiːp]): 由程式員分配釋放,若程式員不釋放,會出現記憶體泄漏
2.2.1 堆區中保存:
- 使用 new 方法創建的對象保存在堆區
- 被創建對象的所有成員變數保存在堆區中
堆區的職責是"解決棧區空間有限的問題"
* OC 使用`new`方法創建的對象
--->{由於 **ARC 管理機制**,OC 程式員通常不需要考慮對象的釋放.}
(在 OC 中,有一個記憶體管理機制,叫做 ARC(自動引用計數)
可以自動管理 OC 代碼創建對象的生命周期)
* C 語言使用 malloc、calloc、realloc 函數分配的空間,需要使用 free 函數釋放
顧: 在開發 OC 程式的時候,程式員通常不需要考慮記憶體釋放的工作
但是:如果在 OC 的代碼中,如果使用到 C 語言分配空間的函數,則需要考慮釋放記憶體
1. 堆區的大小由系統決定,包括:系統記憶體/磁碟交換空間...
2. 系統使用`鏈表`來管理堆區中的記憶體分配情況
3. {**程式員只需要負責堆區中記憶體的分配和釋放工作**}
2.2.2能夠說出堆區的特點
所有程式共用
存儲大數據
程式員管理
: 堆區的記憶體需要程式員管理不連續
: 堆區的地址是不連續的速度沒有棧區快
: 堆區的訪問速度沒有棧區快,因為我們要訪問堆區中創建對象的屬性, 必須先需要通過變數找到棧區的地址,再通過地址定位到到堆區中的某一個位置, 只有找個這個位置之後,我們才可以訪問到存儲到這個對象中屬性對應的數值.由於有了 這個地址尋找的過程,所有速度沒有棧區的快.
0.3 全局變數、靜態變數和常量
3.1 全局變數/靜態變數/常量保存的記憶體區域
開發要讓 變化控制在有限的範圍內
3.1.1 教科書中 全局變數 和 靜態變數 的存儲區域
有初始值的
全局變數 和 靜態變數 保存在 數據段(常量區)沒有初始值的
全局變數 和 靜態變數 保存在 BSS 段(靜態區)
當給 全局變數 或 靜態變數 設置初始值後,會被移動到 數據段(常量區)
3.1.2 Xcode 8 中 全局變數 和 靜態變數 的存儲區域
-
無論是否設置初始值,
全局變數 和 靜態變數
都保存在 BSS 段(靜態區) -
常量
存儲在 數據段(常量區)
註意:(全局/靜態變數,常量)教科書與xcode8驗證有點差別
(1) xcode8 "全局變數"實際存儲區域案例驗證:
案例代碼:
#import <Foundation/Foundation.h>
NSInteger num1 = 10; //定義第一個全局變數 並且初始化
NSInteger num2; //定義第二個全局變數 沒有初始化
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 提示:在 Xcode 8 中,全局變數無論是否初始化,地址保持不變
NSLog(@"第1個全局變數的地址%p", &num1); //第1個全局變數的地址0x100001188
NSLog(@"第2個全局變數的地址%p", &num2); //第2個全局變數的地址0x100001190
num2=100;
NSLog(@"第2個全局變數的地址%p(初始化後的)", &num2);
//第2個全局變數的地址0x100001190(初始化後的)
}
return 0;
}
第1個全局變數的地址0x100001188
第2個全局變數的地址0x100001190
第2個全局變數的地址0x100001190(初始化後的)
Program ended with exit code: 0
可見1:地址從小到大是連續的
可見2:
在 Xcode 8 中,全局變數無論是否初始化,地址保持不變
(2)xcode8 "靜態變數"實際存儲區域案例驗證:
#import <Foundation/Foundation.h>
static NSInteger num1 = 10; //定義第一個全局變數 並且初始化
static NSInteger num2; //定義第二個全局變數 沒有初始化
static NSInteger sNum1 = 10; //定義第一個靜態的全局變數 並且初始化
static NSInteger sNum2; //定義第二個靜態的全局變數 沒有初始化
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 提示:在 Xcode 8 中,全局變數無論是否初始化,地址保持不變
NSLog(@"第1個全局變數的地址%p", &num1); //第1個全局變數的地址0x1000011f8
NSLog(@"第2個全局變數的地址%p", &num2); //第2個全局變數的地址0x100001208
num2=100;
NSLog(@"第2個全局變數的地址%p(初始化後的)", &num2);//第2個全局變數的地址0x100001208(初始化後的)
NSLog(@"##############################################");
NSLog(@"第1個靜態的全局變數的地址%p", &sNum1); //第1個靜態的全局變數的地址0x100001200
NSLog(@"第2個靜態的全局變數的地址%p", &sNum2); //第2個靜態的全局變數的地址0x100001210
sNum2=100;
NSLog(@"第2個靜態的全局變數的地址%p(初始化後的)", &sNum2);//第2個靜態的全局變數的地址0x100001210(初始化後的)
}
return 0;
}
第1個全局變數的地址0x1000011f8
第2個全局變數的地址0x100001208
第2個全局變數的地址0x100001208(初始化後的)
################################
第1個靜態的全局變數的地址0x100001200
第2個靜態的全局變數的地址0x100001210
第2個靜態的全局變數的地址0x100001210(初始化後的)
Program ended with exit code: 0
可見1. 靜態變數的初始化前後地址也是不變的
可見2. 靜態變數和全局變數是交叉保存的
so-->面試註意:
---->在xcode 8中, 靜態變數和全局變數保存在同一個區域
---->在xcode 8中, 靜態變數和全局變數都保存在BSS段中.
跟我們教課書上是有區別的,
so-->當面試中遇到這個問題時,我們可以這樣回答:
在教課書中:BSS段存放的是未被初始化的全局變數和靜態變數,
但是我們通過xcode8 驗證後,他們不管是全局變數
還是靜態變數都存儲在BSS段中.
(3)xcode8 "常量"實際存儲區域案例驗證:
#import <Foundation/Foundation.h>
NSInteger num1 = 10;
NSInteger num2;
static NSInteger sNum1 = 10;
static NSInteger sNum2;
const NSInteger cNum = 10000;//定義一個常量
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"第1個全局變數的地址%p", &num1);
NSLog(@"第2個全局變數的地址%p", &num2);
num2=100;
NSLog(@"第2個全局變數的地址%p(初始化後的)", &num2);
NSLog(@"##############################################");
NSLog(@"第1個靜態的全局變數的地址%p", &sNum1);
NSLog(@"第2個靜態的全局變數的地址%p", &sNum2);
sNum2=100;
NSLog(@"第2個靜態的全局變數的地址%p(初始化後的)", &sNum2);
//第2個靜態的全局變數的地址0x100001230(初始化後的)
NSLog(@"##############################################");
NSLog(@"第1個常量的地址%p", &cNum);
//第1個常量的地址0x100000e88
}
return 0;
}
第1個全局變數的地址0x100001218
第2個全局變數的地址0x100001228
第2個全局變數的地址0x100001228(初始化後的)
#################
第1個靜態的全局變數的地址0x100001220
第2個靜態的全局變數的地址0x100001230
第2個靜態的全局變數的地址0x100001230(初始化後的)
##################
第1個常量的地址0x100000e88
Program ended with exit code: 0
常量存儲演示:面試萬一遇到,可演示一下,解釋與科普書上的不同
可見: 全局變數和靜態變數 跟常量放在不同的區域中,常量存放在常量區(或叫數據段).
* 教科書:數據段(常量區)用來存儲已經初始化的全局變數,靜態變數,常量.
* xcode8:中數據段(常量區)存放的是常量.
3.2 BSS段(靜態區)
存儲的內容: (前面已經案例驗證過了):
1. 教科書: 存儲未初始化
的 全局變數 和 靜態變數
2. Xcode 8驗證: 不管有沒有初始化均存儲 全局變數 和 靜態變數
.
3.3 數據段(常量區)
存儲的內容: (前面已經案例驗證過了):
-
教科書 :存儲
已經初始化
的 全局變數、靜態變數、常量 -
Xcode 8驗證 :不管有沒有初始化
均存儲 常量
.
3.4 全局變數與全局靜態變數的區別
- 若程式只有一個文件,
全局變數
與全局靜態變數
沒有區別 (程式中只有一個文件,幾乎是不存在的,因為通常一個類就對應2個文件.) -
若程式由多個文件構成時,
全局變數
與全局靜態變數
不同:
- 全局靜態變數 通常在定義該變數的文件內部使用 註意:
註意:
1.為什麼OC中幾乎不使用 全局變數?
1. 因為程式的任何一個位置都可以對 全局變數 進行修改
2. 一旦程式出現由全局變數產生的錯誤,不好排查錯誤
3. 使用全局變數不是一個好習慣
[我的理解:因為當我們開發時文件有很多,但是又不能把全局變數定義到頭文件中
(如果定義在頭文件中,當別的類引入該頭文件後,相當於在兩個類中都低定義了該全局變數,
會出現重覆定義),所有幾乎不使用.]
2.不能把 全局變數 定義在頭文件中
(我的理解:如果定義在頭文件中,當別的類引入該頭文件後,相當於在兩個類中都定義了該全局變數,會出現重覆定義)
3.在程式開發時,全局變數 和 靜態變數 都不能重名
(我的理解:當跟別的變數重名時,會被重名的變數修改.)
4.靜態變數 的修改通常只是在 定義當前靜態變數的文件 內部進行
外部即使修改,但是由於地址不同,也不會影響到
定義靜態變數文件
內部的數值變化
一旦程式因為 靜態變數 產生錯誤,只需要在當前文件中,檢查一下修改 靜態變數 的代碼即可,排查錯誤難度相對降低
提示:在程式開發時,如果要使用全局的變數,應該在 .m 中定義一個全局的靜態變數,而不要把該變數暴露在頭文件中-->因為變數範圍越小越可控.
------------------LJXPerson.h---------------------
#import <Foundation/Foundation.h>
//
static NSInteger num1 = 99; //定義一個全局靜態變數
@interface LJXPerson : NSObject
/**
測試方法
*/
- (void)test;
@end
------------------LJXPerson.m---------------------
**LJXPerson.m**
#import "LJXPerson.h"
@implementation LJXPerson
- (void)test{
num1--;
NSLog(@"%p %zd",&num1,num1);
}
@end
------------------main.m-------------------------
#import <Foundation/Foundation.h>
#import "LJXPerson.h"
int main(int argc, const char * argv[]) {
//測試全局的靜態變數
NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
num1=777777;
NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
LJXPerson *xinge=[LJXPerson new];
[xinge test];
LJXPerson *xiaoming=[LJXPerson new];
[xiaoming test];
NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
return 0;
}
在LJXPerson中定義的全局靜態變數的地址0x100001190,99
在LJXPerson中定義的全局靜態變數的地址0x100001190,777777
0x100001198 98
0x100001198 97
在LJXPerson中定義的全局靜態變數的地址0x100001190,777777
通過:上面的輸出結果截圖也對剛纔上面的闡述得到了驗證,以下代碼第6,7,8,13,14行是調用的外部的,即修改的是地址0x100001190對應的變數的值,只有在對象調用方法時是調用的內部的靜態變數.
//測試全局的靜態變數
6. NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
7. num1=777777;
8. NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
9. LJXPerson *xinge=[LJXPerson new];
10. [xinge test];
11. LJXPerson *xiaoming=[LJXPerson new];
12. [xiaoming test];
13. NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
14. return 0;
}
main函數中:註釋掉下麵的代碼
// NSLog(@"在LJXPerson中定義的全局靜態變數的地址%p,%zd", &num1,num1);
// num1=777777;
在LJXPerson中定義的全局靜態變數的地址0x100001190,99
0x100001198 98
0x100001198 97
在LJXPerson中定義的全局靜態變數的地址0x100001190,99
3.5 靜態變數的正確用法
- 先定義局部靜態變數
- static 關鍵字定義的變數在程式執行中
只會被執行一次
- 在 BSS 段為變數分配空間
- 並且設置初始值,如果沒有指定初始值,會使用 0 作為初始值
即: static 關鍵字的作用
- 在 BSS 段為 靜態變數 分配空間
- 為 靜態變數 設置初始值,如果沒有指定初始值,會使用 0 來作為初始值
- static 關鍵字定義靜態變數的代碼,只會被執行一次
------------------聲明---------------------
#import <Foundation/Foundation.h>
@interface LJXPerson : NSObject
/**
測試方法
*/
- (void)test;
@end
-------------------實現--------------------
#import "LJXPerson.h"
@implementation LJXPerson
- (void)test{
static NSInteger num1 = 99; //定義局部靜態變數
num1--;
NSLog(@"%p %zd",&num1,num1);
}
@end
-------------------主程式--------------------
#import <Foundation/Foundation.h>
#import "LJXPerson.h"
int main(int argc, const char * argv[]) {
LJXPerson *xinge=[LJXPerson new];
[xinge test];
LJXPerson *xiaoming=[LJXPerson new];
[xiaoming test];
return 0;
}
2030-03-31 15:12:48.504 demo[5399:535229] 0x100001170 98
2030-03-31 15:12:48.505 demo[5399:535229] 0x100001170 97
Program ended with exit code: 0
3. 如果當前類文件中,有 多個方法
使用到該靜態變數,再將該靜態變數修改成全局的
------------------聲明---------------------
#import <Foundation/Foundation.h>
@interface LJXPerson : NSObject
/**
測試方法
*/
- (void)test;
- (void)demo;
@end
-------------------實現--------------------
#import "LJXPerson.h"
//當前類文件中,有 `多個方法` 使用到該靜態變數,放到全局中
static NSInteger num1 = 99;
@implementation LJXPerson
- (void)test{
num1--;
NSLog(@"%p %zd",&num1,num1);
}
- (void)demo{
num1++;
NSLog(@"%p %zd",&num1,num1);
}
@end
-------------------主程式--------------------
#import <Foundation/Foundation.h>
#import "LJXPerson.h"
int main(int argc, const char * argv[]) {
LJXPerson *xinge=[LJXPerson new];
[xinge test];
[xinge demo];
LJXPerson *xiaoming=[LJXPerson new];
[xiaoming test];
[xiaoming demo];
return 0;
}
0x1000011b0 98
0x1000011b0 99
0x1000011b0 98
0x1000011b0 99
3.6 常量
作用:定義一個
固定不變
的值,全局統一使用,eg:公司網址,電話等
-
const 關鍵字保證其後修飾的常量的值不允許被修改
常量的工作原理:
在 程式被載入到記憶體時,就會為常量分配空間並且設置初始值
在 數據段 為常量分配空間
如果沒有指定初始值,會使用 0 作為初始值 -
不能把 常量 定義在頭文件中
(跟全局變數不能定義在頭文件中一樣,會導致重覆定義) -
應該在 .m 中定義常量
比如我們在LJXPerson.m中定義了一個常量,const NSInteger cNumber =100;這時,這個常量只能在LJXPerson.m中使用,怎麼才能也能在main.m中使用呢,
那就需要下麵介紹的第4個知識點了.
在LJXPerson.h
頭文件中做聲明.extern
const NSInteger cNumber;
特別註意,不能再給設置初始值了,
它已經在其他文件中(eg:在LJXPerson.m中設置值為100了),我們要清楚extern的作用,表示該常量的數值,是在其他文件中設置的,外部可以直接使用此常量)
總之:eg:在.m中: const NSInteger cNumber =100;
eg:在.h中: extern const NSInteger cNumber;
-
在 .h 中使用 extern 關鍵字聲明該 常量 在其他文件設置值
extern的作用: extern關鍵字,表示該常量的數值,是在其他文件中設置的,
外部可以直接使用此常量.
註意:在一個項目中,常量不能重名,因此在定義常量時,應該儘量長,有首碼,以保證不會出現重名的情況
本篇主要學習目標回顧:
記憶體五大區域
程式要執行,首先需要被載入到記憶體
1.1 記憶記憶體五大區域的名稱
能夠說出記憶體五大區域的名稱
棧區
堆區
BSS段(靜態區)
數據段(常量區)
代碼段
1.2 記憶棧區/堆區的職責及特點
能夠說出棧區職責(存儲的內容)
- 局部變數
- 方法實參
能夠說出棧區的特點
512K
連續
從大到小
速度快
系統管理
能夠說出調用方法時棧區的工作原理
開啟棧幀
保存實參
保存局部變數
方法完成後彈棧,銷毀棧幀,釋放空間
能夠說出堆區的職責(存儲的內容)
- OC 使用 new 方法創建的對象 由於 ARC 管理機制,OC 程式員通常不需要考慮對象的釋放
- C 語言使用 malloc 函數分配的空間,需要使用 free 函數釋放
能夠說出堆區的特點
所有程式共用
存儲大數據
程式員管理
不連續
速度沒有棧區快
1.3 記憶全局變數/靜態變數/常量保存的記憶體區域
開發要讓 變化控制在有限的範圍 內
能夠說出教科書中 全局變數 和 靜態變數 的存儲區域
- 有初始值 的 全局變數 和 靜態變數 保存在 數據段(常量區)
- 沒有初始值 的 全局變數 和 靜態變數 保存在 BSS 段(靜態區) 當給 全局變數 或 靜態變數 設置初始值後,會被移動到 數據段(常量區)
能夠說出 Xcode 8 中 全局變數 和 靜態變數 的存儲區域
- 無論是否設置初始值,全局變數 和 靜態變數 都保存在 BSS 段(靜態區) 能夠說出 常量 的存儲區域 常量 存儲在 數據段(常量區) 能夠說出為什麼幾乎不使用 全局變數 開發要讓 變化控制在有限的範圍 內 不能把 全局變數 定義在頭文件中,否則會出現重覆定義 ## 1.4 記憶靜態變數/常量的用法
能夠說出 static 關鍵字的作用
- 在 BSS 段為 靜態變數 分配空間
- 為 靜態變數 設置初始值,如果沒有指定初始值,會使用 0 來作為初始值
- static 關鍵字定義靜態變數的代碼,只會被執行一次!
能夠說出靜態變數的正確用法
* 如果只有一個方法使用,將 靜態變數 定義在方法內部
* 如果有多個方法使用,將 靜態變數 定義在 .m 中
* 不要把靜態變數定義在頭文件中
能夠說出常量的作用
定義一個固定不變的值,全局統一使用,例如公司的網址/電話等...
在 iOS 開發中,通常僅僅在定義 通知字元串 時才會使用到常量
能夠說出常量的正確用法
在 .m 中定義常量並且設置初始值
const NSInteger cNum = 99;
在 .h 中使用 extern 關鍵字聲明常量在其他位置定義並且已經賦值,外部可以直接使用
extern const NSInteger cNum;
常量名應該儘量的長以避免出現重名
結束語
ok! 以上關於記憶體五大區域基礎知識對您起到學習作用了嗎?如果有錯誤之處望指正!謝謝!相關學習共同進步!真心希望其中某個知識點能幫到您!
以上內容目錄結構 (點擊可調轉)
- 00.簡述
- 01. 分配和釋放(面試常被問到)
- 02.棧區和堆區
- 0.3 全局變數、靜態變數和常量
- 本篇主要學習目標回顧:
- 結束語