1、Static、const、extern區別函數
-------------------------------STATIC--------------------------------this
static 全局的,能夠改的,若是在一個類中聲明static,類中其餘地方用到的時候,也是使用的改變量。但不能用類名直接訪問。spa
static 全局變量只能在一個文件中使用,也便是說不可能用extern 使它支持外部引用,而全局變量則能夠經過extern 在外部文件中引用,.net
在真正的開發中,通常要使用的是static 全局變量,爲了防此全局變量名相同時而被別的開發小組用extern引用!設計
.h中3d
OC中的全局變量,(生命週期)從定義變量的那一行直到文件結束指針
方法1:使用靜態變量 (不推薦)對象
方法2: 使用單例模式(static A *a = nil;)生命週期
方法3:把全局變量設置到AppDelegate中(實際也是單例)內存
對於一個完整的程序,內存中的分佈狀況:
==========
| 代碼區 |
------------------
| 全局數據區 |(靜態存儲區)
------------------
| 堆區 |
-----------------
| 棧區 |
==========
通常程序的由alloc產生的動態數據存放在堆區,函數內部的自動變量存放在棧區,全局變量和static變量放在全局數據區
static的做用主要有如下3個:
一、擴展生存期;
二、限制做用域;
三、惟一性
OC
局部變量
做用域: 從定義的那一行開始,直到大括號結束或者遇到break return爲止
存儲位置: 棧
全局變量:
做用域:從定義變量的那一行直到文件結束
存儲位置:靜態區
成員變量:
做用域:建立對象時候有效,對象銷燬(釋放)結束
存儲位置:存儲在對象所在的堆內存中
例如:
A類.h
// 獲取局部靜態變量staticStr
+ (NSString *)sharedLocalStaticStr;
// 獲取全局靜態變量staticStr2
+ (NSString *)sharedGlobalStaticStr;
// 改變全局靜態變量staticStr2
+ (NSString *)changeStaticStr;
A類.m
#import 「A.h"
static NSString *staticStr2 = @"static的使用:全局字符串staticStr2";
@interface ViewController ()
@implementation ViewController
// 獲取局部靜態變量staticStr
+ (NSString *)sharedLocalStaticStr
{
// 局部靜態變量,做用域只限制在此函數,出了這個函數就無法修改staticStr
static NSString *staticStr = nil;
if (staticStr == nil) {
staticStr = @"static的使用:全局字符串staticStr";
}
return staticStr;
}
// 獲取全局靜態變量staticStr2
+ (NSString *)sharedGlobalStaticStr
{
return staticStr2;
}
// 改變全局靜態變量staticStr2
+ (NSString *)changeStaticStr
{
// staticStr無法修改由於它是局部靜態變量;staticStr2k能夠修改由於它是全局靜態變量
staticStr2 = @"static的使用:全局字符串staticStr2被修改";
return staticStr2;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
B類.m引用
// 打印局部靜態變量
NSLog(@"staticStr = %@",[ViewController sharedLocalStaticStr]); staticStr = static的使用:全局字符串staticStr
NSString *staticStr = [ViewController sharedLocalStaticStr];
staticStr = @"static的使用:全局字符串staticStr被修改";
NSLog(@"staticStr = %@",[ViewController sharedLocalStaticStr]); staticStr = static的使用:全局字符串staticStr
NSLog(@"staticStr = %@",staticStr); staticStr = static的使用:全局字符串staticStr被修改
// 打印全局靜態變量
NSLog(@"staticStr2 = %@",[ViewController sharedGlobalStaticStr]); staticStr2 = static的使用:全局字符串staticStr2
NSString *staticStr2 = [ViewController sharedGlobalStaticStr];
staticStr2 = @"static的使用:全局字符串staticStr2被修改";
NSLog(@"staticStr2 = %@",[ViewController sharedGlobalStaticStr]); staticStr2 = static的使用:全局字符串staticStr2
NSLog(@"staticStr2 = %@",staticStr2); staticStr2 = static的使用:全局字符串staticStr2被修改
NSLog(@"staticStr2 = %@",[ViewController changeStaticStr]); staticStr2 = static的使用:全局字符串staticStr2被修改
STATIC:
1、面向過程設計中的static
一、[靜態全局變量] //在全局變量前,加上關鍵字static,該變量就被定義成爲一個靜態全局變量。
靜態全局變量有如下特色:
1)該變量在全局數據區分配內存;
2)未經初始化的靜態全局變量會被程序自動初始化爲0(自動變量的值是隨機的,除非它被顯式初始化);
3)靜態全局變量在聲明它的整個文件都是可見的,而在文件以外(extern)是不可見的;修改只能經過本身類中得函數修改(+ (NSString *)changeStaticStr
)
定義全局變量就能夠實現變量在文件中的共享,但定義靜態全局變量還有如下好處:
1)靜態全局變量不能被其它文件所用;
2)其它文件中能夠定義相同名字的變量,不會發生衝突;
二、[靜態局部變量] 在局部變量前,加上關鍵字static,該變量就被定義成爲一個靜態局部變量。
一般,在函數體內定義了一個變量,每當程序運行到該語句時都會給該局部變量分配棧內存。但隨着程序退出函數體,系統就會收回棧內存,局部變量也相應失效。但有時候咱們須要在兩次調用之間對變量的值進行保存。一般的想法是定義一個全局變量來實現。但這樣一來,變量已經再也不屬於函數自己了,再也不僅受函數的控制,給程序的維護帶來不便。
靜態局部變量正好能夠解決這個問題。靜態局部變量保存在全局數據區,而不是保存在棧中,每次的值保持到下一次調用,直到下次賦新值。
靜態局部變量有如下特色:
1)該變量在全局數據區分配內存;
2)靜態局部變量在程序執行到該對象的聲明處時被首次初始化,即之後的函數調用再也不進行初始化;
3)靜態局部變量通常在聲明處初始化,若是沒有顯式初始化,會被程序自動初始化爲0;
4)它始終駐留在全局數據區,直到程序運行結束。但其做用域爲局部做用域,當定義它的函數或語句塊結束時,其做 用域隨之結束;
三、靜態函數
在函數的返回類型前加上static關鍵字,函數即被定義爲靜態函數。靜態函數與普通函數不一樣,它只能在聲明它的文件當中可見,不能被其它文件使用。
定義靜態函數的好處:
1)靜態函數不能被其它文件所用;
2)其它文件中能夠定義相同名字的函數,不會發生衝突;
2、面向對象的static關鍵字(類中的static關鍵字)
一、靜態數據成員
在類內數據成員的聲明前加上關鍵字static,該數據成員就是類內的靜態數據成員。
靜態數據成員有如下特色:
1)而靜態數據成員被看成是類的成員。不管這個類的對象被定義了多少個,靜態數 據成員在程序中也只有一份拷貝,由該類型的全部對象共享訪問。
2)靜態數據成員存儲在全局數據區,屬於本類的全部對象共享,因此,它不屬於特定的類對象,在沒有產生類對象時其做用域就可見,即在沒有產生類的實例時,咱們就能夠操做它;
同全局變量相比,使用靜態數據成員有兩個優點:
1)靜態數據成員沒有進入程序的全局名字空間,所以不存在與程序中其它全局名字衝突的可能性;
2)能夠實現[信息隱藏]。靜態數據成員能夠是private成員,而全局變量不能;
二、靜態成員函數
它爲類的所有服務而不是爲某一個類的具體對象服務。與普通函數相比,靜態成員函數因爲不是與任何的 對象相聯繫,所以它不具備this指針。從這個意義上講,它沒法訪問屬於類對象的非靜態數據成員,也沒法訪問非靜態成員函數,它只能調用其他的靜態成員函數。
關於靜態成員函數,能夠總結爲如下幾點:
1)出如今類體外的函數定義不能指定關鍵字static;
2)靜態成員之間能夠相互訪問,包括靜態成員函數訪問靜態數據成員和訪問靜態成員函數;
3)非靜態成員函數能夠任意地訪問靜態成員函數和靜態數據成員;
4)靜態成員函數不能訪問非靜態成員函數和非靜態數據成員
--------------------------CONST---------------------------------------
const應用:
1、對於基本聲明
const int r=100;//標準const變量聲明加初始化,編譯器通過類型檢查後直接用100在編譯時替換。
#import "ViewController1.h"
const int constNum = 2;
@interface ViewController1 ()
@end
@implementation ViewController1
- (void)viewDidLoad {
[super viewDidLoad];
// 整數常量
NSLog(@"constNum = %d",constNum); constNum = 2
constNum = 3;(報錯,不讓修改)
}
2、對於指針
1. int x=10; const int *r=&x; //指針指向的內容是常量,r指向的內容不可以經過r改變,但若是是非const,內容能夠經過本身改變,並且r指針能夠改變,能夠指向其它的整形.
//*r=*r+1;NO //x++;YES //r=&y;YES
2. int const *r=&x; 與1徹底相同
3. int * const r=&x; //指針指向是常量,不能修改去指向其它內容,但指向的內容能夠修改
//r=&y;NO //*r=*r+1;YES //x++;YES
4.const int * const r=&x; //綜合一、3用法,r是一個指向常量的常量型指針,指針指向不能改變,指針內容不能改變,內容能夠自身改變 //r=&y;NO //*r=*r+1;NO //x++;YES
extern
假如A類中已經聲明瞭meString,你在另一個B類中想使用這個變量,能夠extern NSString* meString;會獲得a類中一樣的值,且可從新賦值。
// 在A.h中聲明兩個字符串
extern NSString *externStr1; // 定義一個普通的字符串(能夠修改),前面加上extern修飾表示該變量能夠被其餘類導入使用
extern NSString *const externStr2; // 定義一個不可變字符串(不能夠修改)
// 在A.m中初始化兩個字符串
NSString *externStr1 = @"extern的使用:普通字符串externStr1";
NSString *const externStr2 = @"extern的使用:不可變字符串externStr2";
// B類中調用
(1)#import 「A.h"
NSLog(@"externStr1 = %@",externStr1); externStr1 = extern的使用:普通字符串externStr1
NSLog(@"externStr2 = %@",externStr2); externStr2 = extern的使用:不可變字符串externStr2
(2)不導入#import 「A.h"
extern NSString *externStr1;
extern NSString *const externStr2;
NSLog(@"externStr1 = %@",externStr1); externStr1 = extern的使用:普通字符串externStr1
NSLog(@"externStr2 = %@",externStr2); externStr2 = extern的使用:不可變字符串externStr2
注意:
externStr1 = @"extern的使用:普通字符串externStr1被修改";
NSLog(@"externStr1 = %@",externStr1);externStr1 = extern的使用:普通字符串externStr1被修改
externStr2 = @"extern的使用:不可變字符串externStr2被修改」;(報錯,常量不能修改)
// 實際開發中
extern NSString * const AFNetworkingReachabilityDidChangeNotification;// 設置成常量能夠被外部調用,可是外部不容許修改
Code: