2012-07-03 51 views
7

我們是否應該將我們希望保留的所有實例變量轉換爲私有屬性,還是缺少明顯的東西?Objective C ARC和實例變量iOS SDK

@interface SomethingElse : Something { 

    NSMutableArray *someArray; 

} 

在這個例子中,在的someArray與[NSMutableArray裏initWithObject:someObject]的方法進行初始化,但不保留。

我的特殊情況是我正在更新遊戲,有很多實例變量,所以我想確保我爲了未來版本的sdk而正確地做這件事。

回答

1

ARC的版本retain被稱爲strong

基本上,你會使用類似聲明它:

@property (strong) NSMutableArray *someArray; 

What does the "strong" keyword do瞭解詳情。

通常最好使用屬性而不是局部變量,因爲這些屬性爲您提供「免費」的訪問器/設置器,並且通常更易於使用。

+0

謝謝,我理解ARC如何處理屬性,但我的問題是確定現在局部變量是否應該用私有屬性替換(如果我們想保留它們)? –

+0

@BillKervaski:一般來說,是的。請參閱編輯 – houbysoft

+0

Apple建議您不要再顯式聲明變量,除非您有需要。使用屬性,如果需要直接訪問iVar,則可以在合成屬性時設置伊娃名稱,例如:@synthesize myProperty = __myVariable – isaac

0

隨着Obj-C 2.0和更高版本,似乎沒有理由使用iVars。我個人並沒有永遠用過。屬性只是爲你做一切!

+0

使用iVars有很多原因。排在最前面的是:黑客在運行時遇到dylib並且弄亂了你的代碼很難,允許更簡單的C風格陣列,並且比屬性更輕。 –

+0

@ RichardJ.RossIII:關於iVars安全性:它適用於iOS沙盒環境嗎? – user523234

+0

@ user523234是。任何擁有越獄設備的人都可以在您的可執行文件上執行您不希望發生的代碼,並且使用iVars而不是使用屬性代碼更難執行。 –

15

我們是否應該將所有我們希望將 保留的局部變量轉換爲私有屬性,還是我錯過了明顯的東西?

首先,您在示例中顯示的變量是一個實例變量,而不是局部變量。局部變量是在代碼塊內部聲明的(例如,在函數或方法內部,或者在某個子塊內部,如條件語句的主體內部),並且其生命週期僅限於執行聲明它們的塊。實例變量在類中聲明;該類的每個實例都獲取由該類聲明的實例變量的副本。

其次,不需要將所有實例變量轉換爲屬性。 Instance variables are treated as strong references by default under ARC.屬性實際上只是一個承諾,即某個類爲某些訪問者提供了某些語義。只有一個實例變量並不意味着你必須爲該伊娃提供訪問器。 (有些人可能會說你應該是,但你不需要。)

+0

感謝編輯的問題,以正確反映實例變量。我已經讀過實例變量默認爲強,但在我的例子中,對象被解引用(即BAD_ACCESS),這促使我發佈這個,因爲現在我很困惑。 –

3

@property和實例變量是一樣的,除非你使用默認的存儲修飾符,這對於對象來說是強大的。例如,如果您想要@property (copy) NSString *s;或者使用實例變量,並且記得每次設置變量時調用複製,或者使用@property(這更簡單)。

+0

這實際上是唯一一種使用@ @ property來理解私有變量的情況,因爲@ property的任何用法都已經創建了一個變量。 +1。 –

+0

c/local/instance/ –

1

您在其他一些評論中描述了BAD_ACCESS問題。這裏還有別的事情要做。在ARC中,除非另有資格,否則您的ivars是強大的(並且在非ARC中,他們不會以您的名義發佈)。

例如,該ARC代碼工作正常,沒有BAD_ACCESS如您在您的意見報告給其他答案:

@interface ArcTestViewController() 
{ 
    NSMutableArray *_someArray; 
} 
@end 

@implementation ArcTestViewController 

- (void)dealloc 
{ 
    _someArray = nil; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _someArray = [[NSMutableArray alloc] initWithObjects:@"Mo", @"Larry", @"Curly", nil]; 
} 

- (IBAction)checkIvarTouchUpInside:(id)sender 
{ 
    NSLog(@"%s _someArray = %@", __FUNCTION__, _someArray); 
} 

@end 

您可能必須向我們展示你的例子在那裏你得到你的BAD_ACCESS因爲它必須是別的東西。

在回答「財產」或「伊娃」問題時,雖然我同意「總是使用屬性」的論點,但我個人使用任何需要提供外部訪問器的屬性,否則我使用私有ivars(不是在.h中,而是在.m文件中的專用接口中)。這使得我的.h文件中的公共接口在我幾個月後回到他們的時候真的很乾淨並且很容易理解。如果您確實採用了「始終使用財產」的方法,那麼我只會建議您對這些財產的公開聲明應儘可能嚴格(如果可以,請將財產私有化,如果您不願意進行財產的公開聲明不需要提供讀寫訪問等)。

順便說一句,編碼指南爲可可是一個很好的參考最佳做法。

0

非常感謝您的回覆。

如果我請需要與(使用的cocos2d遊戲引擎方法)對象中的方法:

[self schedule:@selector(someMethod) interval:3.0]; 

該目的是解除引用,如果我直接調用它,而不把它在cocos2d的調度器:

[self someMethod]; 

然後仍然有一個有效的指針。只是爲了測試,我保留它,並保持在周圍。

所以現在的問題是我們如何強制保留,以防止ARC認爲我們已經完成並釋放它?

將實例變量更改爲私有屬性可以安全地完成,因此我們將以此作爲答案。

+0

只是澄清 - 你是說,切換伊爾塔到@屬性實際上解決了這個問題?我的問題是與NSMutableDictionary中的對象不保留。 – rrbrambley