簡體   English   中英

創建一個新的 NSString 實例的保留計數為 3

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM