2010-06-09 65 views
1

我是iphone的內存管理新手,並且對標準/正確性有疑問。iphone @property(retain),init()和標準

我的頭文件聲明:

IBOutlet UITabBarController *tabBarController; 
@property (nonatomic, retain) UITabBarController *tabBarController; 

在我的init()的代碼,我在做類似如下:

self.tabBarController = [[UITabBarController alloc] init]; 
[tabBarController release]; 
NSLog(@"Retain count of tbc: %d",[tabBarController retainCount]); 

得到保留計數回一個。從標準化的角度來看,這是否正確?它看起來和我有點不同,但我又是新來的。

感謝

回答

2

分配的屬性,您應該使用

self.tabBarController = [[[UITabBarController alloc] init] autorelease]; 

[tabBarController release]; 
tabBarController = [[UITabBarController alloc] init]; 

(記得先鬆開前值)

Th e屬性setter/getters應全權負責保留/釋放實例變量。如果您(或其他人)更改屬性設置器以獲取輸入副本而不是保留它,會發生什麼情況?在這種情況下,你將過度釋放實例變量並泄漏原始對象。

你實質上是在發送一個具有私人副作用的消息,然後通過在下一行釋放實例變量來使用這些私有細節的知識。即你的代碼是一樣的:

[self setTabBarControler:[[UITabBarController alloc] init]]; 
/* Relying on knowledge of the instance variable is bad here, setTabBarController 
    might do something different in the future */ 
[tabBarController release]; 

即使你是在類的完全控制,你還是應該堅持以抽象和封裝的基本原則。保留/釋放實例變量到底層的屬性實現。

+0

在init方法的第一行釋放一個實例變量是瘋狂的談話。 – hooleyhoop 2010-06-10 09:22:16

+0

我正在從一本書中學習,而這本書推動@property()的;我應該在這種情況下甚至使用這種符號嗎?或者自己處理alloc init? – inyourcorner 2010-06-10 13:00:22

+1

@property()是存取器方法的語法糖。所以問題是你應該使用setter訪問器方法(這就是使用屬性會爲你做的)或不是(無論你需要處理alloc/init)?通常你應該使用setter方法來讓你的屬性的觀察者得到更新通知,但是這在init方法中是不相關的。此外,如果setter方法在子類中被覆蓋,這會導致它在子類被初始化之前被調用 - 而且這會很糟糕。 – hooleyhoop 2010-06-10 13:12:41

1

爲什麼不

tabBarController = [[UITabBarController alloc] init]; 

+0

這對我來說也是有意義的 - 這樣做並省去了合成的setter方法。在這種情況下,我檢查了保留計數 - 現在是2 - 並且發現我自己釋放了這個東西,這對我來說很奇怪。我感謝小費 - 我現在要走這條路線。 – inyourcorner 2010-06-10 23:59:59

1

你可以這樣做,但更好的方法是不要在你的init()方法中使用這種隱式setter語法(因爲如果對象沒有完全初始化,你可能會覆蓋setter並做更多的工作,否則可能無法工作)。

只要做到:

tabBarController = [[UITabBarController alloc] init]; 
+0

如果你把它放在錯誤的地方並且它被多次調用,這可能會泄漏以前的值。例如,在視圖控制器中,在awakeFromNib中可以,但不是viewDidLoad。 – progrmr 2010-06-09 12:47:26

+1

@progrmr:我指的是init()方法,我猜'tabBarController'在調用init()之前不會有另一個值。 – 2010-06-09 12:55:31

3

這很正常。

你做什麼:

id *tempVar = [[UITabBarController alloc] init]; 
self.tabBarController = tempVar;     //till now, retainCount is 2 
[tabBarController release];      //now, retainCount is 1 

當你的alloc它,這個內存塊將通過一個臨時變量保留:

self.tabBarController = [[UITabBarController alloc] init]; 
[tabBarController release]; 

可能由編譯器作爲執行。所以更好的方法是:

UITabBarController *tabCtl = [[UITabBarController alloc] init]; 
self.tabBarController = tabCtl; 
[tabCtl release]; 

我不是專家的對象c,只是有一些關於編譯的知識。所以,如果我錯了,請指出這裏的專家。