Using alloc, init in ARC enabled projects
Asked Answered
L

3

7

Actually I am working on a project with ARC enabled. I know using alloc and init is taking ownership of the object. I know, If I create a string like this

NSString *myString = [[NSString alloc]initWithFormat:@"Something"];

then I need to release the myString on myself. What If I am using ARC enabled? I cannot release on myself. So will it create a leak? Or should I don't create object like this?

I can create a string like below code too.

NSString *myString = [NSString stringWithFormat:@"Something"];

But which type I need to use exactly for ARC enabled project ? What will happen if I use first type?

Lazurite answered 21/11, 2012 at 14:31 Comment(0)
F
16

If you use ARC, all the necessary release calls will be added for you when you compile. It will not leak.

The difference between

NSString *myString = [[NSString alloc]initWithFormat:@"Something"];

and

NSString *myString = [NSString stringWithFormat:@"Something"];

is that the first one will automatically released after the last reference to myString in that block, while the second one is an autoreleased instance that will only be released at the end of the run loop. It's not a big difference, but if you're using a lot of objects, try to avoid autoreleased ones to keep memory usage low.

Fortenberry answered 21/11, 2012 at 14:35 Comment(7)
If I am using large number of temporary objects, I need to use the first way. Right??Lazurite
It would be a better choice, yes. Or, you could also use an @autorelease{} pool to release autoreleased objects before the end of the run loop. Check out the WWDC videos about ARC.Fortenberry
ok. I understood. One more doubt. Instead of using objects, If I am using lot of temporary primitive type variables? still autorelease pool will release those variables??Lazurite
No. Objective-C memory management (both manual and ARC) only manages memory for Objective-C objects. Primitive types are different. They are allocated on the stack and come and go as functions are called and return. If you malloc primitive pointers on the heap, you have to free them yourself, but that's completely independent from releasing objects in Obj-C.Fortenberry
ok ok I get it. I thought those primitive types also make too much memory. Now I get it. They are not reference counting. Anyway thank you so much.Lazurite
The second pattern may not produce an autoreleased object as the compiler might optimize that pattern to eliminate the autorelease. It would do so, for example, if NSString were compiled with ARC enabled.Vite
Are you sure? Do you have a source? Not that I don't believe you.Fortenberry
C
1

ARC takes care of the memory management, so no you don't need to worry about calling release on your myString variable, ARC will do that for you. Also as a suggestion I would recommend using convenience methods to create your object such as

[NSString stringWithFormat:@"Something"];

Cellule answered 21/11, 2012 at 14:34 Comment(0)
H
0

It's enough to set the string pointer to nil to release it.
You can also do the same things that you would be able to do without ARC, but with the advantage that if you don't explicitly do anything, the ARC will manage (almost) everything for you.

So to release it you set it to nil, let's see what else you could do:

    NSString* str= [[NSString alloc]initWithUTF8String: "Hello"];
    // here the retain count of str is 1
    __unsafe_unretained NSString* string= str;
    // again 1 because string is __unsafe_unretained
    void* data= (__bridge_retained void*) string;
    // data retains the string, so the retain count is to 2
    // This is useful in the case that you have to pass an objective-c object
    // through a void pointer.You could also say NSString* data= string;
    str=nil;
    // Here the retain count of str is 1
    NSLog(@"%@",(__bridge NSString*)data);

UPDATE

Here's why sometimes you don't notice that an object is released:

    NSString* str= [[NSString alloc]initWithString: @"hey"];
    __unsafe_unretained NSString* str2=str;
    str=nil;
    NSLog(@"%@",str2);

In this case str=[[NSString alloc]initWithString: @"hey"] is equal to str=@"hey", with the difference that str is autoreleased and not released.But the compiler optimizes the code in str=@"hello", so if you are inside an autorelease block you won't have any problem, str2 will be printed correctly.
That's why I used initWithUTF8String, to avoid that compiler optimization.

Hidie answered 21/11, 2012 at 15:9 Comment(2)
I don't think setting nil is gonna release the object. For instance If I create an object like this NSString *myString = nil; is it getting released so??Lazurite
Yes it does.Without ARC if you try to release a nil object it doesn't create problems, nil targered actions are ignored.I don't known how the ARC is implemented, maybe it sends a nil targered release message, or maybe it does in some other way.Hidie

© 2022 - 2024 — McMap. All rights reserved.