2013-04-29 50 views
1

我試圖更好地理解強引用,但是在下面列出的特定示例的上下文中。強烈的引用(目標-C)

可以說我有一個名爲gPrefs的全局變量。它是一個Preference Class類型,是我製作的一個自定義類。

我在它的界面如下聲明...

@property (strong) NSURL   *masterFolder; 

這是一個指向對象NSURL。我已經給出了它(強)的參考,這意味着它會堅持下去,而不是釋放它的記憶。

現在讓我們說我有一個實例函數完全在其他地方,如下所示。

- (IBAction)masterDataSelectButtonAction:(id)sender 
{ 
    NSOpenPanel *openPanel = [NSOpenPanel openPanel];//creates an open panel. 
    [openPanel setCanChooseDirectories:YES]; 
    [openPanel setCanChooseFiles:NO]; 

    NSInteger panelResult = [openPanel runModal]; 

    if(panelResult == NSFileHandlingPanelCancelButton){ 
     NSLog(@"masterDataSelectButtonAction -> Cancel Button Pressed"); 
     return; 
    } 

    if(panelResult == NSFileHandlingPanelOKButton){ 
     NSLog(@"masterDataSelectButtonAction-> Ok Button Pressed"); 
     NSURL *theUrl = [openPanel URL]; 
     gPrefs.masterFolder = theUrl; //Setting (strong ref) point to local. 
     [_masterDataLabel setStringValue:[gPrefs.masterFolder absoluteString]]; 
    } 
} 

如果用戶按下了面板的OK按鈕,我創建了一個名爲theUrl的本地指針實例變量。然後,我將全局變量masterFolder指針設置爲本地實例變量指針。

如果我理解正確,ARC應該在函數結束時釋放對象,當它認爲它不再被使用時。

因此,uUl應該在函數結束時釋放。但是,如果我理解(強)引用,編譯器可能足夠聰明,因爲我將全局首選項指針更改爲不同的指針,所以它將使其他指針在內存中保持活動狀態(或保留它)。

如果我沒有聲明我的masterFolder指針爲(強),那麼在函數結束後,masterFolder指針是否爲零?

我的實驗表明,儘管到達本地實例函數的末尾,但保持它(強)似乎仍保留localInstance指針的值。

我的問題是爲什麼?即使masterFolder是一個強引用,如果我將它分配給一個localInstance指針,並且該實例函數結尾處的指針被刪除,爲什麼masterFolder的值不是NIL,當我再次從實例函數外讀取它時。

我對(強)參考文獻的理解有點(弱)。沒有雙關語意。

回答

3
NSURL *theUrl = [openPanel URL]; 

theURL是在函數的範圍(或if塊內,但是,這並不使在該示例中的差)。 theURL指向的對象在堆上。在該函數結束時,當theURL超出範圍時,堆上對象的引用計數將減少1(因爲theURL是對該對象的強引用。如果此時引用計數變爲0,在你的情況下,至少還有一個強對象引用(在你的全局單例中),所以對象保持活動狀態。堆中的對象不是任何東西的本地對象,因此內存不會超出範圍。

如果全球單有一個弱引用一次對象的引用數爲0,將被自動設置爲nil和對象被釋放。

+0

所以,如果我理解正確的話,強大的屬性將只工作在NSObject,我試過了像INT這樣的基本類型,並且由於INT不是指針類型或對象的明顯原因而失敗。我認爲它也會在結構上失敗。除此之外(因爲我知道這是一個單獨的問題)...當(強)被引用的'對象'指針被設置爲另一個指針時,它將確保將新指針值保留在內存中,直到變量與強烈的參照最終被刪除。讓我知道,如果我走在正確的軌道上。我認爲只有NSObject可以做到這一點? – 2013-04-29 06:21:56

+0

'strong'和'weak'只用於對象,因爲它們對簡單類型(沒有引用計數)沒有意義。對於簡單的類型(比如'int'和'struct'),你使用'assign',所以這個值被賦值(即複製)給你的屬性。 – Sebastian 2013-04-29 22:49:28

2

如此強大的確實只是保留。當您撥打gPrefs.masterFolder = theUrl;時,您正在做的是將指針masterFolder設置爲與theUrl相同,並將保留設置爲masterFolder。因此,創建theUrl時,其保留計數爲1;當設置爲masterFolder的強屬性時,theUrl保留了對它的保留調用,它將保留計數增加到2.這就是爲什麼在實例方法完成並且發生初始自動釋放的情況下它不會消失,theUrl仍然存在由於它被設置爲強大的財產,因此保留計數爲1。

現在,如果你屬性設置爲弱,你會得到masterFolderniltheUrl一旦autorelease它發生弱簡單地設置masterFolder是一樣theUrl但不調用保留被正確地破壞的行爲在上面。