+[NSString stringByAppendingString:] creates a new, auto-implemented object every time you call it. Authorized objects are not freed until an autocomplete pool appears, which usually means at the end of an event loop. In this case, it is best to use NSMutableString as other answers indicate. But if you encounter a problem when you need to create many objects with auto-implementation instead of using a mutable object, you can wrap the @autoreleasepool {} block around the code that creates the objects so that you do not have massive memory to swell, but you have to be careful. to save objects that you want to stick out of @autoreleasepool .
In general, I try to avoid using auto-implemented objects as much as possible for several reasons:
1) When objects are actually freed, it can be non-deterministic if you actually do not have an autostart pool in your method itself. Otherwise, there is no way to find out the size of the auto settlement pool, and when the calling code decides to fill the pool.
2) Autorealizators are inherently more resource intensive than manual release. Objects must be added to the pool, then repeated and released later.
3) Auto-implementers become especially complex in a multi-threaded environment, because often you can race between threads that free an object. In these situations, it is easy to create an intermittent failure scenario that is difficult to reproduce or find the root cause.
4) Failure, as a rule, is much more difficult to analyze when working with auto-implementations. You will often see stack traces, which are just an autoplay pool that pops an object, and without replication it is almost impossible to determine which object, which code path frees it, etc.
5) Sometimes, something as simple as refactoring can affect auto-implemented objects in ways that are not normally expected. The transition from simple iteration to block-based iteration is an autostart pool that can free an object before you can save it.
Usually the most appropriate use of auto-implemented objects is objects that are created "on the fly" and returned by the non-constructor method. Thus, the calling code has the ability to save the object, but the called method should not worry about the appointment of the owner.
It was a rather long exhaustion and perhaps beyond the scope of the original question, but I think it is important to know the βwhyβ behind good decisions in memory management.