How to properly initialize objects in objective c with ARC - objective-c

For many classes there are initXXX methods and typeXXX methods, for example:
NSNumber *n1 = [[NSNumber alloc] initWithInt:1];
NSNumber *n2 = [NSNumber numberWithInt:1];
I've read about manual memory management and I think that I understand how those lines are different with manual memory management (second is just shortcut for autoreleased object).
But with ARC I don't understand which API I should use? Should I use only alloc-init pattern because ARC is smart enough to make value autoreleased if necessary and avoid autorelease overhead when value is only used locally? Or ARC can optimize out autorelease and corresponding overhead even when I use something like numberWithInt?
I would like to use second variant when available, because it's shorter and easier to read. But I don't want to introduce performance overhead just for this reason.

Or ARC can optimize out autorelease and corresponding overhead even when I use something like numberWithInt?
It can, even with these convenience factory (so are they called) methods. Here all is explained well.
So you can use either one.

Related

__bridge_transfer and performSelector:withObject:

I have a CFDictionaryRef that doesn't retain/release its objects. When I add an item in it, I take care of retaining it, and later :
NSMutableArray *array = (__bridge_transfer NSMutableArray *)CFDictionaryGetValue(...)
[self performSelector:someSelector withObject:array];
Where someSelector is a variable holding a selector I know about. Now, that second line makes Xcode tell the notorious warning:
PerformSelector may cause a leak because its selector is unknown
Does that mean I should worry about ARC not knowing how to manage memory for the array variable of which I just transferred ownership?
From a comment to the accepted answer of this question, it appears that somebody at Apple has confirmed this hypothesis (citing the answer itself):
In fact, there are times when memory management is tied to the name of the method by a specific convention. Specifically, I am thinking of convenience constructors versus make methods; the former return by convention an autoreleased object; the latter a retained object. The convention is based on the names of the selector, so if the compiler does not know the selector, then it cannot enforce the proper memory management rule.
Thus, it has nothing to do with a possible leak of arguments passed to the performSelector: call, but rather to its returned value, for which Objective-C has no way of knowing if it was autoreleased or not. This is also what Martin R from the comments was assuming.

Is AutoRelease redundant when using ARC in Objective-C?

I'm pretty new to Objective-C, as you may gather, and until recently, I hadn't really understood the need for all this AutoRelease malarky. I think that's mostly because I've started Objective-C with ARC, and haven't had any exposure to doing retains and release.
Anyway, my understanding now is that pre-ARC, if you created an object and needed to return a pointer to it as the returning object of the method/function, you would need to autorelease it, because you are unable to do the "[obj release]" after doing "return obj;"
Worrying about retains and releases isn't an issue with ARC. Does this mean that in our own code, there is really point in creating our own autoreleased objects? Ie, doing [[[Class alloc] init] autorelease]? From what I've gathered, we should still setup autorelease pools, but only because other frameworks or libraries may still return autoreleased objects, but we no longer need to explicitly create autoreleased objects ourselves - is this a fair understanding?
Thanks,
Nick
When using ARC, you do not want to do any memory management yourself. Specifically you will not be calling release and auto release because it does it all for you. In fact, the compiler should probably complain if you try to manage memory yourself.
Instead of [[[Class alloc] init] autorelease]; you'll just call [[Class alloc] init];
I recommend reading this blog post for some really good background on ARC and memory management in general.
Well, your understanding is quite correct. With ARC we do not release or autorelease any more. Just have to make sure that we assign nil (or some other reasonable value) to any reference to objects, which we do not need any more. In the worst case we could still constantly consume additional memory but the memory cannot leak any ore.
And yes, we still maintain autorelease pools for the sake of using framework libraries (linked ones) that may not use ARC.
To answer your question between the lines about the purpose of autorelease. This applies to non-ARC project only, of course.
In the good old days Objective-C did not offer any reference counting but its retain counting. Any allocated memory of objects, that are not retained (or have a retain count of 0) is considered free and may soon be claimed and used by other objects.
This means that every object needs to be retained after its allocation, assuming that you want to keep it around. When the object is not used any more then you need to release it. This comes with two risks. Well, alloc does retain it once automatically.
1) You may forget to release an object that is unused. In the worst case you may even loose all references to an object that stays in memory for ever since.
2) You may still refer to an object hat has been released already and then try accessing it which will most likely end in an BAD_EXC exception.
All this can be quite annoying. In order to get rid of some of these obligations for objects that don't stay around very long, the autorelease was invented. For temporary objects only you alloc it (release-count = 1) and autorelease it. That means that the object will be automatically released (retain count reduced by 1) within the next autorelease circle. But the object remains allocated for your method while it is being executed. Typically the reference variable would be a local one.
Sample:
-(void) myMethod{
AClass *someObject = [[[AClass alloc] init] autorelease];
// use the object
// probably hand it to another object if that takes ownership, i.e. add it ot an Array using addObject:
// don't care any more
}
And that not required any more when using ARC.

Under ARC, is it still advisable to create an #autoreleasepool for loops?

Let's say that I have a loop that returns a bunch of autoreleased NSData objects...
NSData* bigData = ...
while(some condition) {
NSData* smallData = [bigData subdataWithRange:...];
//process smallData
}
Under ARC, should I still wrap an #autoreleasepool around the while condition?
NSData* bigData = ...
#autoreleasepool {
while(some condition) {
NSData* smallData = [bigData subdataWithRange:...];
//process smallData
}
}
The reason why I'm asking is I see the living allocation count in instruments going through the roof for my NSData objects that invoke a dataWith... method as opposed to an initWith... method. When I use initWith..., the living allocation count is much, much less.
Is it better to prefer the initWith... methods whenever possible?
Yes you should still use autorelease pools when using convenience methods in a tight loop. All the old memory management rules still apply under ARC, the compiler is merely injecting RRs for you. Checkout the great post by the awesome Mike Ash!
Link
I think your issue is that the autorelease pool is supposed to go inside the loop. With the loop inside the autorelease block rather than vice-versa, the accumulated objects won't be released until after the loop finishes.
Under ARC, should I still wrap an #autoreleasepool around the while condition?
Yes. Autorelease Pools are still in place, and grow and pop as before. The compiler just adds and coalesces the necessary retains and releases operations when ARC is enabled (echoing Logan), based on the methods that are visible to the TU and default naming conventions.
Execution in ARC is nearly identical the manual reference counting: Autorelease pool stacks still exist. One difference is that the compiler may order the reference counting operations slightly different from the way you wrote it (not in an incorrect way), and may omit unnecessary retain cycles.
Is it better to prefer the initWith... methods whenever possible?
WRT minimizing heap growth compared to the autoreleased counterparts: Yes. That's always been the case. It's especially important on iOS devices, where memory is quite limited.
The exception to this is when the object may avoid an allocation. Example:
NSString * copy = [NSString stringWithString:arg];
in this case, copy may be [[arg retain] autorelease]. Note that in this case, copy is still autoreleased, but you should not usually go to great lengths to test the presence of such optimizations. Note: It's also better to use copy = [arg copy]...[arg release] here.
The other bonus is that your ref count imbalances are often caught earlier when the object is never autoreleased, and closer to the call site (rather than when the Autorelease Pool is finally popped).
Performance with large autorelease pools is actually much worse than most people would suppose. If you can avoid depending on them heavily (e.g. using alloc+init...+release), you can make your program noticeably faster. Explicitly creating autorelease pools is cheap, and can help minimize this problem. When allocations are large and/or numerous, avoid using autorelease on them where possible, and do wrap these sections in explicit autorelease pools.

Performance of factory methods in Objective-C

Is there any difference performance-wise in the following 2 snippets of code?
NSString* str = [[NSString alloc] initWithFormat:#"%i", 10];
// Do something with |str|.
[str release];
NSAutorelasePool* pool = [[NSAutreleasePool alloc] init];
NSString* str = [NSString stringWithFormat:#"%i", 10];
// Do something with |str|.
[pool drain];
I see people trying to suggest using factory methods whenever possible.
Isn't it better to release objects as soon as possible rather than when a pool is drained.
I would see the first type being very efficient in certain cases such as in tight-loops.
I see people trying to suggest using
factory methods possible.
I'd guess that's because it's basically the same thing, but you don't have to remember to release the object. Some might say that using the convenience method is a little more readable, too, especially since you don't have to end every method with a sequence of -release messages.
Isn't it better to release objects as
soon as possible rather than when a
pool is drained.
You can make that case in some situations, such as inside a loop. That's often not an important consideration, though... many methods don't loop at all and only create a handful of objects.
I would see the first type being very
efficient in certain cases such as in
tight-loops.
Sure. So you should know when it is and when it isn't appropriate to autorelease objects, and you should write your code accordingly. But it doesn't follow that you should always try to avoid autoreleasing objects any more than it makes sense to always try to use convenience methods.
BTW, if you're writing loops that iterate many times, you should consider creating an autorelease pool. Chances are, you'll be using other methods inside your loop, and those methods might create autoreleased objects. Using your own pool and draining it periodically prevents those objects from piling up. If you do that, though, it takes a great deal of wind out of the the idea that you shouldn't use autoreleased objects in your loop.
Yes it is. First one is better memory management, worth it if you are doing it, like you said, in a loop to avoid allocating a lot before the next pool drain.

What's the difference between an [[alloc]init] and a [[thing]retain]?

I was wondering, what (if any) is the difference between creating objects using:
NSThing *thing = [[NSThing alloc] initWithObject:object];
vs
NSThing *thing = [[NSThing thingWithObject:object] retain];
Is there a difference in how the memory management works? Also, when is it common practice to use one vs the other?
Allocating and initialising an object is slightly more efficient, because thingWithObject: will do an alloc, then init, then autorelease which you counter with a retain, so you add something to the autorelease pool. The first option only involves an alloc and a init.
Personally, I use the explicit alloc when I want to be clear that the object's lifetime will be handled by me, and I use the convenience methods (thingWithThing:) for any object that I won't need outside of the scope it is created in.
For example, explicitly allocating and initialising within a loop is generally preferred, so that you don't flood the autorelease pool. I also use an explicit alloc+init rather than thingWithThing: + retain for objects that need to survive an iteration of the run loop.