附加到 NSString 时正确的内存管理

发布于 2024-12-15 16:23:22 字数 689 浏览 3 评论 0原文

我已经分配了一个 NSString 对象。我想在应用程序的整个生命周期中偶尔附加到该字符串 我对如何正确处理下面示例中的内存感到困惑。谢谢。

  1. 我是否需要保留每次附加的字符串,或者是否可以附加属于自动释放池的字符串,如 stringByAppendingString: 返回?
  2. 每次执行追加操作时,我是否都会泄漏之前分配给 my_string 的内存?

代码:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];
NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
my_string = [[my_string stringByAppendingString:something_else] retain];
[my_string release];

I have an NSString object that I've allocated. I want to append to this string occasionally throughout the lifetime of the app
I am confused about how to properly handle the memory in the example below. Thanks.

  1. Do I need to retain the string that I am appending each time, or is it OK to append with a string that belongs to the autorelease pool, as stringByAppendingString: returns?
  2. Am I leaking the memory that was previously assigned to my_string each time I do an append?

Code:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];
NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
my_string = [[my_string stringByAppendingString:something_else] retain];
[my_string release];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倥絔 2024-12-22 16:23:22
NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];

不是自动释放的(因为它是使用 init... 方法创建的,这是约定),它的保留计数为 1。

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];

是自动释放的。

是否可以附加属于自动释放池的字符串,如
stringByAppendingString:返回

只要您期望它存在就可以。但是在您的代码中:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];

您有泄漏。您应该在重新分配 my_string 之前自动释放它。所以最后一行应该是:

my_string = [[[my_string autorelease] stringByAppendingString:something] retain];

否则你将永远失去指向你应该释放的对象的指针。当你保留结果时,你有责任释放它,所以你在最后一行之前也有泄漏,这应该是

my_string = [[[my_string autorelease] stringByAppendingString:something_else] retain];
NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];

is not autoreleased (as it is created with an init... method, this is a convention), it has a retainCount of 1.

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];

is autoreleased.

is it OK to append with a string that belongs to the autorelease pool, as
stringByAppendingString: returns

As long as you would expect it to live for yes. However in your code:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
my_string = [[my_string stringByAppendingString:something] retain];

you have a leak. You should autorelease my_string before re-assigning it. So the last line should be:

my_string = [[[my_string autorelease] stringByAppendingString:something] retain];

otherwise you have forever lost the pointer to the object you are meant to have released. As you retain the result, you are responsible for releasing it so you also have a leak in the line before last which should be

my_string = [[[my_string autorelease] stringByAppendingString:something_else] retain];
百思不得你姐 2024-12-22 16:23:22

首先要记住的是 NSString 是不可变的。无论您是分配、使用格式创建还是追加,您总是会返回一个字符串对象。那么让我们来分解一下:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
//String object created with "Initial string" content. Retain +1

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
//String object created with content " with something" and autoreleased.

my_string = [[my_string stringByAppendingString:something] retain];
//String object created with content "Initial string with something", autorelesed, and retained. Effective retain +1
//Assignment replaces old "Initial string" reference. "Initial string" object still has retain of +1, so it doesn't get deallocated (it leaks).

NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
//String object created with content " and something_else" and autoreleased.

my_string = [[my_string stringByAppendingString:something_else] retain];
//String object created with contents "Initial string with something and something_else", autoreleaased, and retained. Effective retain +1
//Assignment replaces old "Initial string with something" reference. "initial string with something" object still had a retain of +1, so the object leaks.

[my_string release];
//String object "Initial string with something and something_else" released. Retain -1. Object is deallocated and doesn't leak.

//...Sometime later at the end of the runloop, the autorelease pool is drained and " with something" and " with something_else" are both deallocated.

所以:

  1. 是的。附加一个自动释放的字符串就可以了。在运行循环结束之前(至少是在该方法退出之后),不会对自动释放的对象调用 release

  2. 是的,每次执行追加时,您都会泄漏之前分配给 my_string 的对象...但导致泄漏的不是追加,而是分配。您可以将 nil 分配给 my_string,并且如果您不release,用于指向的保留对象 my_string 仍然会泄漏code> 或 autorelease 首先。

The primary thing to keep in mind is that NSString is immutable. Whether you alloc, create with format, or append, you're always getting a new string object returned. So let's break this down:

NSString* my_string = [[NSString alloc] initWithString:@"Initial string"];
//String object created with "Initial string" content. Retain +1

NSString* something = [NSString stringWithFormat:@"%@", @" with something"];
//String object created with content " with something" and autoreleased.

my_string = [[my_string stringByAppendingString:something] retain];
//String object created with content "Initial string with something", autorelesed, and retained. Effective retain +1
//Assignment replaces old "Initial string" reference. "Initial string" object still has retain of +1, so it doesn't get deallocated (it leaks).

NSString* something_else = [NSString stringWithFormat:@"%@", @" and something_else"];
//String object created with content " and something_else" and autoreleased.

my_string = [[my_string stringByAppendingString:something_else] retain];
//String object created with contents "Initial string with something and something_else", autoreleaased, and retained. Effective retain +1
//Assignment replaces old "Initial string with something" reference. "initial string with something" object still had a retain of +1, so the object leaks.

[my_string release];
//String object "Initial string with something and something_else" released. Retain -1. Object is deallocated and doesn't leak.

//...Sometime later at the end of the runloop, the autorelease pool is drained and " with something" and " with something_else" are both deallocated.

So:

  1. Yes. It's ok to append an autoreleased string. release is not called on an autoreleased object until the end of the run loop, which, at the very least, is after this method exits.

  2. Yes, you are leaking the objects that were previously assigned to my_string each time you do an append... but it's not the append that's causing the leak, it's the assignment. You could assign nil to my_string and the retained object my_string used to point to would still leak if you didn't release or autorelease it first.

叹梦 2024-12-22 16:23:22

在第二个作业中,您将丢失第一个 stringByAppendingString 调用的保留引用,因此:

  1. 可以在不调用保留的情况下附加字符串,除非您稍后在代码中需要该值。
  2. 是的,每次调用 stringByAppendingString 都会返回一个新的自动释放字符串。如果您暂时使用该值,请勿保留它。

In the 2nd assignment you're losing the retained reference of the first stringByAppendingString call, so:

  1. It's OK to append with a string without calling retain, unless you're needing the value later in the code.
  2. Yes, each call to stringByAppendingString returns a new autoreleased string. Don't retain it if you're using the value temporarily.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文