1

我有一些像這樣的代碼:如何防止從C++調用Obj-C消息時自動保留/釋放?

@interface MyTimer : NSObject 
- (int)getValue; 
@end 

@interface TimerHolder : NSObject { 
    ExternalControl* m_externalControl; 
} 
@property (retain, nonatomic) MyTimer* timer; 
@end 

class ExternalControl { 
    __unsafe_unretained TimerHolder* m_holder; 
public: 
    ExternalControl(TimerHolder* holder) : m_holder(holder); 
    int getTimer() { return [m_holder.timer getValue] }; 
}; 

方法ExternalControl::getTimer()被稱爲非常頻繁。在分析過程中,我注意到在撥打電話getTimer()期間,obc-j還會調用objc_retainobjc_release(推測在m_holder或m_holder.timer上),最終耗費大量時間!刪除__unsafe_unretained沒有什麼區別。

通過構建,我知道每當調用ExternalControl::getTimer()時,m_holder及其定時器將在調用期間保持活動狀態,所以我認爲保留/釋放是不必要的。

有什麼辦法可以阻止他們被叫?

我在iOS 5 SDK中使用XCode 4.2,並啓用了ARC。 ARC是否負責並刪除它將刪除保留/發佈? (我不想花時間重新創建一個沒有ARC的項目,只是爲了測試這個,然後再和我的朋友們覈對一下!)

+1

對我來說,它看起來像這個代碼違反了ARC規則之一,即不要在C結構中存儲對象指針(C++類在此實例中計算爲C結構)。所以正確的答案可能是不使用ARC來處理這個文件。 http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html – JeremyP

+0

爲什麼不把答案寫成答案而不是評論? – squelart

+0

我不記得爲什麼不。也許我不覺得它正確回答了這個問題。那時我沒有做ARC編程。 – JeremyP

回答

1

我只能說非ARC體驗,因爲我沒有使用它但(並沒有計劃它是老派)。

但是,我有幾個項目使用C++庫並在obj-C代碼中保留引用。 我知道,除非明確要求,否則不會調用保留/釋放。

順便說一句,我連接C++庫時不能使用Obj-C,而是必須使用Obj-C++,否則C++構造函數/析構函數不會按預期方式調用。這只是將.m文件重命名爲.mm

希望得到這個幫助。

+0

謝謝,這似乎指向ARC作爲罪魁禍首。是的,我正在使用Obj-C++。 – squelart

+0

刪除ARC後,額外的保留/釋放消失。 – squelart

2

如果您想手動處理該類的保留/釋放(禁用ARC)。 在該源文件的構建階段選項卡中設置「-fno-objc-arc」編譯器標誌。

0

關於ARC的WWDC 2011會議特別提到,爲編譯調試時,ARC保留/版本沒有優化。

如果還沒有,請嘗試在發佈模式下運行代碼並對其進行分析。你應該看到顯着的差異。

但是,我知道ARC沒有考慮到當你說「通過構造」時你暗示的那種設計假設。但是,ARC不應該觸及你的「__unsafe_unretained」實例變量......你確定那些保留/釋放調用正在傳遞一個指向的指針

+0

我剛剛檢查過,並且默認情況下「配置文件」方案建立在發佈模式中。所以我猜他們沒有優化我的這個特殊用法...這看起來很公平,因爲不能保證我的C++代碼在Obj-C對象被銷燬時無法運行,所以他們不能只刪除這些保留/釋放,除非我能以某種方式告訴編譯器我的意圖。 – squelart

+0

但是你的「__unsafe_unretained」正在告訴你有關你的意圖......如果我知道ARC試圖保留/釋放那個......我會很震驚*這種行爲會違反你設置的合同。其他事情正在發生。 – Steve

+0

據我所知,__unsafe_unretained告訴編譯器這個變量包含一個指針,並且如果指針被銷燬,這個指針不會自動被清零。因此,編譯器試圖通過保留對象來保護用戶是有道理的,從而防止正在使用的版本。 我的意圖是通知編譯器一些更像「__unsafe_retained」的東西,其中我知道*該對象必須保留在別的地方,所以沒有必要爲我保留它。 :-) – squelart