如何解决这会导致 NSString 泄漏吗?
我是一名 C 程序员,但对 Objective-C 还是很陌生。我已经多次看到这样的 NSString 相关代码:
NSAppleScript* script = [[NSAppleScript alloc] initWithSource: @"<some script code>"];
...
[script release];
上面的代码显式地释放了 NSAppleScript 对象,但似乎没有在任何地方释放 NSString 对象。
我想知道 [script release]
是否会自动完成 NSString 对象的隐式释放工作,所以我将上面的代码更改为以下内容:
NSString* scriptText = @"<some script code>";
NSAppleScript* script = [[NSAppleScript alloc] initWithSource: scriptText];
...
[script release];
//If [script release] has implicitly released scriptText,//this would cause a repeated release.
[scriptText release];
但是上面的代码运行起来也很好。这是否意味着 [script release]
不会自动释放 NSObject 对象?也就是说,第一节的代码是不是泄露了NSString的释放?
解决方法
非常简短的回答:不。你不应该释放 scriptText
。 (事实上,你不能。)
在 ObjC 手动引用计数中,您需要遵循基于方法名称的规则。如果您调用名称以 alloc
或 new
开头或包含 copy
的方法,则您有责任在该对象上调用 release
或 autorelease
还给你。此外,如果您在对象上调用 retain
,则您有责任调用 release
或 autorelease
。
按照规则,您调用了 +[NSAppleScript alloc]
,因此您负责对返回给您的对象调用 release
。您没有调用保留方法来获取 scriptText
;您使用了 NSString 文字 (@"..."
)。所以你不能在它上面调用 release
。它不会泄漏。 (如果确实如此,则表明 Apple 代码中存在错误。)
实际工作的方式是 NSString 文字直接存储在二进制文件中,就像在 C 中一样。不需要管理它们,因为它们不直接使用内存。但这与您在手动引用计数下的义务无关。你不应该认为“这是一个字符串文字,所以我不应该在它上面调用 release
”。这根本不是真的。当规则告诉您调用 release
时,您应该调用 release
。对碰巧是文字的值调用 retain
是完全正确的,然后在其上调用 release
是完全正确的。 (这种情况一直发生。您通常不知道您使用的 NSString 是否是文字。)
在 NSString 文字上调用 retain
或 release
恰好是真的。他们只是不理会电话。内存中甚至不存在非常短的 NSString 对象。如果它们足够短,数据将直接存储在指针中(称为“标记指针”)。同样,这只是一个实现细节。你的工作是遵守规则,而不是试图猜测系统。
(带有额外 release
的错误代码“有效”的原因是文字 NSStrings 忽略内存管理调用。代码仍然不正确。也不能保证过度释放对象会导致崩溃在任何情况下,当它发生崩溃时,它发生在一个随机点,远离错误是非常非常常见的。对象有待处理的 autorelease
调用是非常常见的,所以你得到池排水时崩溃,没有提示您的错误在哪里。)
当然,您应该打开 ARC 并让它为您处理。它做得很好。但无论如何了解规则是有帮助的。 ARC 使用相同的基于名称的规则来确定放置保留和发布的位置。这就是它如何与手动内存管理无缝交互。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。