Why does ARC use an abstract?

I run this code using no autocomplete pool in ARC:

- (NSString*) outName { if (!outName) { outName = [[NSString alloc] initWithFormat:@"whatever"]; // or stringWithFormat } return outName; } 

The debugger says that every time a single outName instance is outName without a pool in place.

This will not happen if I change the code to

 - (NSString*) outName { if (!outName) { outName = @"whatever"; } return outName; } 

What I can not do (this example is clearly simplified). In addition, the leak message disappears if I create an autostart pool in the calling code (which I would like to avoid).

Why does ARC insist on autoreleasing this object, which is stored in the strong property? And more importantly, how can I avoid this warning?

+4
source share
4 answers

This is a matter of ownership.

Let's talk about the NSString that you highlighted first. When you allocate an object, memory on the heap is reserved for this object (unless you allocateWithZone: to another location). The save count is implicitly 1, and you own the object, i.e. You are responsible for his release when you are done. If you are going to return a pointer to this object, i.e. By returning this object, you will not completely disclaim liability for the object not to leak. You cannot release it, because the save counter will be 0, and this object will be canceled. You automatically check this, ensuring that at the end of the execution loop (or earlier) the object will be released and possibly freed. The calling function is responsible for storing the returned object if the returned object must survive longer.

Without an auto-calculation pool, you will leak out because the designated autoReleasePool is null (remember that its value is null, so this is not just a failure, but just a leak).

The fixed @ example does not leak, because the compiler reserves the program memory for this line, and -release does not affect them. The same is true for some low value NSNumbers.

As James said, ARC does not remove the concept of conservation and auto-advertising.

EDIT: how is outName declared as ivar / property?

+2
source

Jared's answer is good, but part of the work of ARC is to use naming conventions. The outName method outName means it returns autoreleased , so if there was de-ARC-ifier, your last line would look like this:

 return [[outName retain] autorelease]; 

Obviously, this requires an autostart pool.

This does not happen in your second example, because you are returning a constant, therefore saving / auto-detection is optimized.

0
source

When ARC returns ivar (or any object) to the calling method, it must ensure that it will not be released until the completion of the current RunLoop. As a programmer, you know that he will never be released, but ARC relies on algorithmic guarantees (best practices). ARC will call retain] autorelease] if the variable does not point to a constant (not created using NARC ) and therefore is not at risk of being released.

You should not avoid this warning. You need to fix your code. You can add an auto resource pool. If you don't want to do this, another way is to push the logic that uses ivar to the object that ivar actually holds.

0
source

Strange, I have a very similar method that I use and it does not flow. It looks like this:

 -(NSString *) dataFilePath { NSString *appendPath; if (isPowerMode==YES) { appendPath = kDataFileNamePower; } else { appendPath = kDataFileNameClassic; } NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; return [documentsDirectory stringByAppendingPathComponent:appendPath]; } 

So, perhaps from there you will want to declare an empty NSString pointer at the beginning of the method and populate and return it instead of outName.

-1
source

All Articles