本文說說static在iOS中的做用包括OC和Swift,並講解經常使用的狀況.代碼主要以OC爲主,Swift中主要描述和另一個關鍵字class的異同bash
- (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了
複製代碼
- (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".當再次調用時不須要從新生成.節省內存函數
#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都是用來描述類型做用域這一律念.二者均可以用來修飾計算類型.均可以用來修飾方法,static修飾的方法叫作靜態方法,class修飾的是類方法.(在OC中咱們不會特別的區分類方法,類變量,靜態方法,靜態變量),可是在Swift中class和static,不管是可以修飾的範圍仍是修飾後產生的效果區別都很大,不能混爲一談.spa
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 iOSProgrammer :Programmer{
// 重寫計算屬性 可使用static 來重寫,可是static 重寫後,就不能被它的子類再次重寫了
static override var nickname: String{
return "iOS王重陽"
}
// 重寫類方法時可使用static 讓其變成靜態方法
static override func writeTheCode() -> Void {
print("寫代碼")
}
}
複製代碼