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