[英]Creating a new NSString instance has retain count of 3
我正在嘗試復制一個傳遞給這樣的方法的字符串:
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
NSLog( @"elementName, %@: %i", elementName, [elementName retainCount] ); // rc = 2
if ( currenttag )
[currenttag release];
NSLog( @"currenttag: %i", [currenttag retainCount] ); // rc = 0
//currenttag = [[NSString alloc] initWithString:elementName]; // track current element
[self setCurrenttag:elementName];
NSLog( @"currenttag: %i", [currenttag retainCount] ); // rc = 3
.
.
.
}
setCurrenttag
是一個綜合訪問器( @property (copy)
)。 我的理解是,這將創建一個全新的 object 而只是對elementName
的引用。 上面的行為就好像它保留了對elementName
的引用並調用了 retain。 注釋掉的代碼顯示了相同的行為。
這些方法正在實現NSXMLParserDelegate
協議,但我確實需要跟蹤某些元素名稱(但不是全部)。
關於 iphone 上的NSString
對象和 memory 管理,我是否缺少一些東西。
另外,作為參考,我正在使用 XCode 3.6 的 iPhone 模擬器上運行它。
對於像 NSString 這樣的不可變 Foundation 類, copy
只保留 object。 復制已知不可變的 object 會浪費資源,因此不會發生。 這在 NSCopying 協議的文檔中有所暗示。 實現該協議的選項之一是:
- 當 class 及其內容不可變時,通過保留原始副本而不是創建新副本來實現 NSCopying
一般來說,如果您知道您的某個類的實例將是不可變的,那么保留目標 object 而不是復制它是完全有效的。
不要指望retainCount
是直觀的。 這里可能發生的情況是有問題的字符串是不可變的,因此“副本”最終只保留現有的字符串(這很好,因為它永遠不會改變)。
每當您處理對象時,您絕不能直接處理保留計數,您必須僅根據差異來處理它們。 你必須知道的是保留是+1,釋放是-1
只是一個猜測,但由於NSString
是不可變的,因此該屬性執行retain
而不是創建新的 object 可能是一種優化。
不要相信retainCount。 只需釋放您調用 alloc、copy、retain 和 new 的每個 object。
以我的經驗,retainCount 並不總是返回實際的保留計數,而且它可能很棘手。 NSString 是一個不可變的 object,因此它的行為可能與其他對象不同,我不確定 Objective C 是否實現了像 java 這樣的字符串池,因為文檔中沒有提到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.