2012-08-04 45 views
1

我有一類稱爲面板,包含弱屬性是這樣的:弱屬性調用objc_storeStrong

@屬性(非原子,弱)對話框*容器;

在Instruments中,我可以看到setContainer方法最終調用objc_storeStrong。

這是正確的嗎?我認爲這些弱財產並沒有增加保留數量。

我的init()方法如下:

- (id) initWithContainer:(Dialog *)pContainer{ 
    self = [self init]; 
    if (self) { 
     self.container = pContainer; 
    } 
    return self; 
} 

請指點。 謝謝,

+0

現在,這不可能是好的。你確定這是什麼調用objc_storeStrong?因爲它似乎是您的情況違背了[CLANG ARC參考(http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime.objc_storeStrong)。 – CodaFi 2012-08-04 01:56:47

+0

我正在使用模擬器。我已經檢查並確保ARC在項目設置中處於打開狀態,並且目標是使用Apple LLVM編譯器3.1。我敢肯定,我可以在儀表以下調用堆棧指針看到一個額外保留對話框:4 DialogPanel initWithContainer:] 3 DialogPanel setContainer:] 2 libobjc.A.dylib objc_storeStrong 1 libobjc.A.dylib objc_retain 0 CoreFoundation - [NSObject retain] – mikemeli 2012-08-04 02:26:36

回答

0

你應該得到一個objc_storeStrong消息發送,但不是容器屬性。它發送給你的arg,因爲局部變量會自動傳遞並保留(如果沒有指定weak),並在賦值時保留。當你的方法返回時,arc爲你自動釋放arg。

+0

我實際上看到兩個保留和一個版本。這就是爲什麼我詢問了setContainer中的額外保留。參數保留/釋放發生在OK(成對)中。 \t 0xae3a600對話框\t \t保留2 \t 00:11.258.360 \t - [DialogPanel initWithContainer] \t 0xae3a600對話框\t \t保留3 \t 00:11.258.450 \t - [DialogPanel setContainer: ] \t 0xae3a600對話框\t \t推出2 \t 00:11.258.453 \t - [DialogPanel initWithContainer] – mikemeli 2012-08-04 02:38:11

+0

當然。 Arc保留方法參數,然後在函數返回時釋放它們。 – CodaFi 2012-08-04 02:45:31

+0

但爲什麼我看到第二個保留setContainer方法調用?這會增加總體保留計數,並且對象永遠不會被釋放。 – mikemeli 2012-08-04 02:49:23

0

使用儀器的榮譽。

首先,您應該直接在init/dealloc中使用iVar。

二,你自己綜合它,還是自己實施二傳手?

另外,你運行調試或發行優化的代碼?

現在,解釋爲什麼我用更多的問題回答你的問題。

如果合成它自己(即宣告自己的實例變量,你也必須聲明,作爲__weak。如果你讓編譯器做到這一點,它會妥善處理。

現在,你顯然因此,編譯器會自動添加代碼來執行手動引用計數(其中一些可能會在稍後由優化器刪除)。現在,我並不假裝自己是編譯器創建的專家,但是,它將非常接近以下內容

以一個基本任務爲例...

- (void)setContainer(Container*)container { 
    _container = container; 
} 

當編譯器完成其注入代碼ARC,這將是這個樣子(假設_container未聲明__weak)...

// Converted by ARC -- so it's MRC 
- (void)setContainer(Container*)container { 
    [container retain]; 
    Container *oldContainer = _container; 
    _container = [container retain]; 
    [oldContainer release]; 
    [container release]; 
} 

現在,讓我們更進了一步,假設_container是__weak ,我們得到這樣的事情...

- (void)setContainer(Container*)container { 
    [container retain] 
    Container *oldContainer = [_container retain]; 
    objc_storeWeak(&_container, container); 
    [oldContainer release]; 
    [container release]; 
} 

現在,objc_storeStrong是分配給一個變量強的順序,所以很明顯,其中,將適合在上面的代碼。

此外,請注意,編譯器是如何審慎添加代碼的。優化器非常具有侵略性,並且可以移除顯然不需要的大多數保留/釋放對。因此,在大多數情況下,您將在函數中看到用於保留/釋放的不同語義,具體取決於您是構建調試還是發佈。

但是,一般來說,除非指定__unsafe_unretained,否則您必須期望至少獲得任何參數的保留。

1

感謝大家的幫助,同時調試此問題。我非常感謝。我的知識是正確的,而弱點不會增加保留數。不幸的是,我花了幾個小時來調試這個問題,最終結果是Instruments選擇了一箇舊版本的應用程序,該應用程序的構建沒有使屬性變得虛弱。我不知道這是怎麼發生的,因爲我從Xcode項目中啓動了樂器,做了一個乾淨的等等......但是有些錯誤,因爲當我啓動樂器時,它會問我樂器兩次,而不是一次,然後改爲要自動啓動應用程序,我必須通過選擇目標來手動啓動它(這是錯誤的,因爲它通常會自動啓動應用程序。)我通過退出樂器,Xcode和模擬器並再次重新啓動來解決問題。謝謝!