Static關鍵字理解(iOS)

Static修飾局部變量:

  • 當static關鍵字修飾局部變量時,只會初始化一次。
    例 1:
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    [self test];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    NSLog(@"---------- viewWillAppear -------------");
    [self test];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    NSLog(@"---------- viewDidAppear -------------");
    [self test];
}

- (void)test {
    NSInteger i = 0;
    i++;
    
    static NSInteger staticValue = 0;
    staticValue++;
    
    NSLog(@"i = %ld, s.value = %ld", (long)i, (long)staticValue);
}

@end

打印結果:


1535336913623.jpg

  • 當static關鍵字修飾局部變量時,在程序中只有一份內存。
    例 2:
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    [self test];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    NSLog(@"---------- viewWillAppear -------------");
    [self test];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    NSLog(@"---------- viewDidAppear -------------");
    [self test];
}

- (void)test {
    NSString *normalString;
    static NSString *staticString;
    
    NSLog(@"normal = %p, static = %p", &normalString, &staticString);
}

@end

打印結果:


1535336222431.jpg

從打印結果可以看出,Static修飾的局部變量在程序中只有一份內存(如圖結果:0x104358ef8)。


  • Static關鍵字不可以改變局部變量的作用域。
    例 3:


    1535338718265.jpg

    如圖中所示,我在test方法中定義了一個static修飾的局部變量staticValue,如果想在其他方法中直接使用這個變量則會報錯:變量未聲明,所以可以得出結論:Static關鍵字修飾的局部變量只限制在當前作用域范圍內使用(即不可改變其作用域)。


  • Static關鍵字可延長局部變量的生命周期。
    這個觀點我們還是借助 例1 的代碼來說明。在例1中我們定義了一個普通局部變量i和一個static修飾的局部變量staticValue,分別讓他們自增1,然后輸出結果,在打印結果中我們看到普通局部變量的值永遠是1(每當調用一次函數,就會定義一個新的變量每次i的值都是零,自增后就是1),而static修飾的局部變量的值會一直增長(被static修飾的變量只會初始化一次,永遠都只有一份內存),我們可以得出 Static關鍵字可延長局部變量的生命周期,直到程序結束才銷毀

Static修飾全局變量:

  • 當static關鍵字修飾全局變量時,作用域僅限于當前文件,外部類是不可以訪問到該全局變量的。

默認情況下,全局變量在整個程序中是可以被訪問的(即全局變量的作用域是整個項目文件)

#import "SLStaticDemo.h"

NSInteger age;

@implementation SLStaticDemo

@end
#import "ViewController.h"

NSInteger age;

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    age = 20;
    
    NSLog(@"age = %ld", (long)age);
}

在工程SLStaticDemo.m文件中聲明一個全局變量NSInteger age;,同時在ViewController.m文件中聲明一個全局變量NSInteger age;,然后編譯會報錯:

1535349477718.jpg

通過錯誤信息我們可以知道全局變量age重復聲明,所以可以驗證 全局變量的作用域是整個項目文件


要解決這個錯誤信息,我們可以在全局變量前面添加static關鍵字,把全局變量的作用域縮小到當前文件,保證外部類無法訪問(即使在外部使用extern關鍵字也無法訪問)。

#import "SLStaticDemo.h"

static NSInteger age;

@implementation SLStaticDemo

@end

Extern關鍵字

在上面我們提到extern關鍵字,那這個關鍵字的作用是什么呢?我們還是用上面的代碼來理解extern關鍵字的作用(注意:代碼中全局變量的定義 NSInteger age = 10; 并沒有static)。

#import "SLStaticDemo.h"

NSInteger age = 10;

@implementation SLStaticDemo

@end
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    extern NSInteger age;
    NSLog(@"age = %ld", (long)age);
    
    age += 10;
    NSLog(@"age = %ld", (long)age);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

打印結果:

1535351089734.jpg

從輸出結果 age = 10 我們可以看到即便我們在ViewController.m中并沒有import SLStaticDemo.h也能得到SLStaticDemo中定義的age變量,這就是extern關鍵字的功勞(extern可以訪問全局變量);

如果不想讓外部類訪問全局變量,則可以在定義全局變量時加上static關鍵字。

總結:

  1. static關鍵字修飾局部變量:
  • 當static關鍵字修飾局部變量時,只會初始化一次且在程序中只有一份內存;
  • 關鍵字static不可以改變局部變量的作用域,但可延長局部變量的生命周期(直到程序結束才銷毀)。
  1. static關鍵字修飾全局變量:
  • 當static關鍵字修飾全局變量時,作用域僅限于當前文件,外部類是不可以訪問到該全局變量的(即使在外部使用extern關鍵字也無法訪問)。
  1. extern關鍵字:
  • 想要訪問全局變量可以使用extern關鍵字(全局變量定義不能有static修飾)。

全局變量是不安全的,因為它可能會被外部修改,所以在定義全局變量時推薦使用static關鍵字修飾。

參考鏈接:https://blog.csdn.net/gezi0630/article/details/51993934

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.static (1)修飾局部變量 用static聲明局部變量時,則改變變量的存儲方式(生命期),使變量成為靜態...
    濟公活佛是小松鼠閱讀 865評論 0 1
  • 1 原理 1.1 首先,關于聲明和定義的區別。 這種寫法(函數原型后加;號表示結束的寫法)只能叫函數聲明而不能叫函...
    Pitfalls閱讀 6,576評論 2 12
  • 1.static (1)修飾局部變量 用static聲明局部變量時,則改變變量的存儲方式(生命期),使變量成為靜態...
    iOS俱哥閱讀 657評論 0 4
  • 卡爾?鈕波特《深度工作》。書中將深度工作定義為:在無干擾的狀態下專注進行職業活動,使個人的認知能力達到極限。書中提...
    芷榮說閱讀 801評論 0 0
  • 現在很多人經常說的一句話就是現在壓力太大了,尤其是生活在在北上廣深這樣的一線城市的人,高昂的房價和不斷攀升的生活-...
    國璽同學閱讀 577評論 0 1