說說iOS中的經常使用的關鍵字static ,class(僅限Swift關鍵字)

本文說說static在iOS中的做用包括OC和Swift,並講解經常使用的狀況.代碼主要以OC爲主,Swift中主要描述和另一個關鍵字class的異同bash

當static修飾局部變量時

  1. 變量在內存中的位置: 當用static修飾局部變量時,局部變量的內存地址會從棧變爲全局區(靜態區)
  2. 做用域:只在函數內部可見,只初始化一次,因此也只有一個內存地址
  3. 生命週期程序結束時才釋放
- (void)viewDidLoad {
    [super viewDidLoad];
    [self tobeYoung];
    [self tobeYoung];
    [self tobeYoung];
    static int age = 20;//使用static修飾的局部變量,在其餘的函數中聲明相同變量名的變量時,是一個全新的變量
    NSLog(@"age===%d",age);
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)tobeYoung {
    static int age = 10;
    age--;
    NSLog(@"age===%d",age);
}
// 控制檯的輸出結果
2018-11-29 22:46:31.602384+0800 static[1260:222387] age===9
2018-11-29 22:46:31.602557+0800 static[1260:222387] age===8
2018-11-29 22:46:31.602672+0800 static[1260:222387] age===7
2018-11-29 22:46:31.602758+0800 static[1260:222387] age===20
//每次的輸出結果都不同,被static修飾的局部變量內存地址只有一份,只被初始化一次,全部第二次調用tobeYoung方法時age沒有被從新初始化,因此是9,9--以後就是輸出8了
複製代碼
  1. 經常使用狀況講解:咱們常常在tableViewcell複用的時候使用到static,爲何須要在局部變量identifier以前加上static.咱們先看看經常使用的寫法
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
    static NSString * identifier = @"cellIdentifier";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    return cell;
}
複製代碼

tableview的這個代理方法是一個會被反覆調用的方法,當identifier的前面不加static修飾時,identifier這個臨時變量是儲存在棧中的,指向常量區中的@"cellIdentifier",一旦這個代理方法執行完畢,identifier這個局部變量就會被回收.當再次調用的時候又會從新生成一個局部變量從新指向常量區的@"cellIdentifier".,消耗內存.ide

當使用static修飾identifier時,identifier的內存就會被分配在全局區(靜態區),生命週期會變成這個程序的運行時間,不會隨着代理方法調用完畢而銷燬,一直指向常量區的@"cellIdentifier".當再次調用時不須要從新生成.節省內存函數

當static修飾全局變量時

  1. 內存中的位置 :仍然是在靜態儲存區沒變,生命週期爲整個程序運行期間.
  2. 做用域 :在整個聲明它的文件中可用,在聲明他以外的文件以外不可見
  3. 經常使用狀況:iOS中的單例中的全局變量會用static修飾
#import "Singleton.h"

@implementation Singleton
static Singleton * instance = nil;
+ (Singleton *)getInstance{
    if (instance == nil) {
        instance = [[Singleton alloc] init];
    }
    return instance;
}

+ (id) allocWithZone:(struct _NSZone *)zone{
    if (instance == nil) {
        instance = [super allocWithZone:zone];
        
    }
    return instance;
}
- (id) copyWithZone :(struct _NSZone*)zone{
    
    return instance;
}
@end

複製代碼

爲何必定要用static 來修飾變爲一個靜態變量,而不是寫成一個實例變量.由於單例是程序生命週期中惟一的實例,爲確保實例化的惟一.而利用類的類方法來生成,而在類方法中不可使用實例對象的變量,只能使用屬於類的(static)類變量(通常在OC中沒有特地區分static變量和類變量的區別).並且在聲明它以外的文件不可見.ui

/**
     在其餘的類中實用extern來訪問
     */
    extern Singleton * instance ;
    NSLog(@"instance====%@",instance);
    
    直接沒法編譯過會直接報錯
    Undefined symbols for architecture x86_64:
  "_instance", referenced from:
      -[ViewController viewDidLoad] in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

複製代碼

在Swift中static的使用(包含與關鍵字class的異同)

說道Swift中的static那就不得不說到另外一個關鍵字class,在Swift中static和class都是用來描述類型做用域這一律念.二者均可以用來修飾計算類型.均可以用來修飾方法,static修飾的方法叫作靜態方法,class修飾的是類方法.(在OC中咱們不會特別的區分類方法,類變量,靜態方法,靜態變量),可是在Swift中class和static,不管是可以修飾的範圍仍是修飾後產生的效果區別都很大,不能混爲一談.spa

  • class 和 static相同點
  1. 均可以在class中修飾方法,static修飾的叫作靜態方法,class修飾的叫作類方法.
  2. 均可以修飾class中的計算屬性
class Programmer :NSObject {
    
    static var name : String{
        return "老王"
    }
    class var nickname :String {
        return "王重陽"
    }
    class func writeTheCode() -> Void {
        print("寫代碼")
    }
    static func fixTheBug() -> Void {
        print("修復bug")
    }
    
}
複製代碼
  • class 和static中的不一樣點
  1. 首先class修飾的屬性和方法能夠被子類重寫,可是static不能被重寫
    class修飾的類方法被重寫時,可使用static修飾,讓方法變成靜態方法,但它的子類就不能重寫了 class修飾的計算屬性被重寫時,可使用static修飾,讓其變成靜態變量,但它的子類就不能重寫了
class iOSProgrammer :Programmer{
    // 重寫計算屬性 可使用static 來重寫,可是static 重寫後,就不能被它的子類再次重寫了
    static override var nickname: String{
        return "iOS王重陽"
    }
    // 重寫類方法時可使用static 讓其變成靜態方法
    static override func writeTheCode() -> Void {
        print("寫代碼")
    }
    
}
複製代碼
  1. 其次class 和static可以修飾的範圍不同,class只能在class中修飾,而static能夠不只能夠做用於class中,也能夠在enum,和struct中使用.
    通篇有限今天暫時到此爲此,若有錯誤,但願你們幫忙在評論中指出,歡迎你們來交流溝通.
相關文章
相關標籤/搜索