假設有分配像下面
NSString *placeHolder = [NSString stringWithFormat:@"%@ %@",[someObject value1], [someObject value2]];
現在一個局部變量這個變量傳遞給一個對象中定義的方法,例如的UISearchBar對象的setPlaceholder
[self.theSearchBar setPlaceholder:placeHolder];
如何在正確的釋放方式分配的字符串'placeHolder'?
如果你想給autoreleas它:
NSString *placeHolder = [[NSString stringWithFormat:@"%@ %@",[someObject value1], [someObject value2]] autorelease];
代碼如果你想釋放傳遞到其他地方後,可變像
[self.theSearchBar setPlaceholder:placeHolder];
[placeHolder release];
一個將失敗,bad_exc_access
運行時異常也會拋出。
那麼,怎麼了?
問題是保留計數。該對象的UISearchBar分配還,所以如果你釋放或自動釋放這樣一個變量,這個對象指,保留計數還是一樣
NSLog(@"Retain count before assign to refer other object %d", [placeHolder retainCount]);
[self.theSearchBar setPlaceholder:placeHolder];
NSLog(@"Retain count after referencing %d", [placeHolder retainCount]);
那麼,該如何處理呢?
嘗試像下面
[placeHolder retain]; // retainCount +1
[self.theSearchBar setPlaceholder:placeHolder];
[placeHolder release]; // retainCount -1
我們做什麼能比?讓我們來看看保留計數現在
NSLog(@"Retain count before doing retain %d", [placeHolder retainCount]);
[placeHolder retain]; // retainCount +1
NSLog(@"Retain count after retaining it %d", [placeHolder retainCount]);
所以,我們遞增保留計數之前爲它分配(得到由參考)一些對象, - 後 - 我們釋放本地是可變的。
就是這樣。
在上面的代碼中有多個返回路由是不好的做法,一個是顯式的,一個是隱式的。你應該將返回移動到[release]下面,想象很多if()語句,每個語句都返回,這是很多重複的代碼。 – 2010-02-17 21:45:24
爲什麼它是不好的做法,因爲它很難遵循?看起來好像跟着一堆,如果邏輯可能同樣複雜。 – 2010-02-17 23:02:32
當你有30個地方需要複製並且超過一個發佈代碼塊時,並且當你添加一個需要[發佈]的東西時,你現在必須更新30個地方。它違反了DRY本人(不要重複自己)。 如果你有一個返回值,最好的做法是在邏輯中設置返回值,然後在函數的底部返回該值,就在你的[release]塊單點之後。 – 2010-02-18 20:47:38