2010-09-15 41 views
1

我正在閱讀教程書。當我看到一個例子時,我感到困惑。 以下代碼顯示延遲加載的方式。實例釋放後,這個動機數組是否會被釋放?或者它會佔用這個內存塊直到應用程序終止。關於延遲加載的內存

+ (NSArray *)motivations 
{ 
    static NSArray *motivations = nil; 
    if (!motivations) 
    { 
     motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil]; 

    } 
    return motivations; 
} 

編輯1 感謝喬治的一個bug。

回答

2

因爲它是一個靜態對象,所以系統將存儲對象指針,直到應用程序終止。你可以用這種方式來緩存您的指針指向讓一個對象不是releaseautorelease

我建議,當你真的想在內存中緩存一些數據(通常是大或小的圖像數據)採用此方法,需要大量的CPU或IO處理時間才能生成。對於像NSString這樣的小數據,您可以創建新的數組並在每次需要時返回。

編輯的評論: 大約有imageNamed:

1 2米的東西/你不能控制緩存,什麼是不被imageNamed:緩存。例如,您可能不想緩存大尺寸的圖像,而僅使用一次。

2/imageNamed:不能用於從網絡或系統中的文件夾獲取圖像。它只會從你的包中加載

+2

請注意,'static'隻影響指針'motivations'的存儲,數組的生命期完全獨立於它。 – 2010-09-15 02:49:19

+0

至於圖像,在iPhone SDK下,imageNamed會將圖像緩存在系統中。是否有必要再次在代碼中緩存圖像? – AechoLiu 2010-09-15 03:06:13

+0

有兩件事:1 /你不能控制imageNamed,它會緩存什麼,什麼不會。例如,您肯定不想緩存3或10 MB的映像。 2 /無法使用imageNamed加載所有圖像,例如,圖像位於系統中的特定路徑或從互聯網下載的圖像 – vodkhang 2010-09-15 03:13:38

3

你顯示的例子有一個錯誤 - +arrayWithObjects:返回一個自動釋放的實例,稍後將被銷燬。代碼可能是:

motivations = [[NSArray alloc] initWithObjects:@"Greed",@"Revenge",@"Bloodlust",@"Nihilism",@"Insanity",nil]; 

這樣,數組將一直存在,直到應用程序終止。

+0

嗯,我什至沒有注意到這個bug – vodkhang 2010-09-15 02:39:44

+0

^^「謝謝,我也沒有注意到這個bug – AechoLiu 2010-09-15 03:00:51

+1

我把這個作爲一個錯誤提交給靜態分析器(分析器應該捕獲autoreleased對象被分配到靜態變量):http://llvm.org/bugs/show_bug.cgi?id=4955 – 2010-09-15 05:06:30

1

由於這是一個類方法(由聲明中的+而不是 - 表示),因此不會發布任何實例。 (從技術上講,我認爲有一個isa類對象的實例(如果我錯了,請注意,我不知道內部工作原理)但是不用擔心)

所以班級,它在程序運行的整個過程中存在於內存中,擁有該數組。把靜態看作和你可以到達一個類變量一樣近,而不是一個實例變量。由於這個類一直存在,所以這個數組存在整個時間。

延遲加載使它不被創建,直到第一次調用類方法爲止,所以它不會浪費內存直到你需要爲止。