2009-02-16 42 views
42

我在看下面的蘋果示例源代碼時:使用Objective-C中static關鍵字定義一個變量緩存

/* 
Cache the formatter. Normally you would use one of the date formatter styles (such as NSDateFormatterShortStyle), but here we want a specific format that excludes seconds. 
*/ 
static NSDateFormatter *dateFormatter = nil; 
if (dateFormatter == nil) { 
    dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:@"h:mm a"]; 
} 

試圖找出:

  • 爲什麼使用靜態關鍵詞?

  • 如果在每次調用方法時將其設置爲nil,它將如何等於緩存變量。

的代碼是從實施例4中Tableview Suite demo

回答

62

靜態變量通過重複調用函數保留其分配的值。它們基本上像全局值,只對該功能「可見」。

但是,初始化語句只執行一次。

此代碼在第一次使用函數時將dateFormatter初始化爲零。在每次後續的函數調用時,都會根據dateFormatter的值進行檢查。如果沒有設置(這隻會在第一次是真的),則會創建一個新的dateFormatter。如果它被設置,那麼將使用靜態的dateFormatter變量。

值得熟悉靜態變量。它們可能非常方便,但也有缺點(在這個例子中,例如不可能釋放dateFormatter對象)。

只是一個提示:有時候可以在代碼中放置一個斷點並看看發生了什麼。隨着程序的複雜程度的提高,這將成爲無價的技能。

16

static」功能是指「不上等號的右邊評估的東西通過簽署每次使用之前的值改爲」在這種情況下。

以極大的責任使用這個偉大的力量:你冒着使用大量記憶的風險,因爲這些是永不消失的物體。除了像NSDateFormatter這樣的情況之外,這很少合適。

+10

我知道這是老問題,但不知道這個靜態關鍵字與ARC的關係的影響? – codejunkie 2012-01-13 21:25:58

+3

@ codejunkie靜態存儲在與堆不同的位置。 ARC關心保留和釋放堆內存,以便值可以保持超出堆棧幀。因此,我懷疑ARC對靜態變量有什麼影響。 – smileBot 2014-03-14 20:32:11

1

爲了便於參考,這是我如何使用我的日期格式化程序的靜態在表視圖控制器中使用。

+ (NSDateFormatter *) relativeDateFormatter 
{ 
    static NSDateFormatter *dateFormatter; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     //NSLog(@"Created"); 
     dateFormatter = [[NSDateFormatter alloc] init]; 
     [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; 
     [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 
     NSLocale *locale = [NSLocale currentLocale]; 
     [dateFormatter setLocale:locale]; 
     [dateFormatter setDoesRelativeDateFormatting:YES]; 
    }); 
    return dateFormatter; 
}