繁体   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