How to Set Property Value in Objective-C the Right Way - objective-c

I might've jumped into Objective-C a little too fast and assumed I knew enough about memory management to dive in. Turns out I wasn't.
Fast forward a bit and I've caught up ... for the most part. One of my last remaining questions regards the #property/#synthesize process and setting those values properly.
I've often seen this:
SomeObject *obj = [[SomeObject alloc] init];
self.obj = obj;
[obj release];
It makes sense, but I wonder if this accomplishes a similar enough thing to be an alternative:
self.obj = [[[SomeObject alloc] init] autorelease];
Would that be acceptable anywhere you might set the value of the #property, obj? Or is direct access to the instance variable preferred over both of those in the init method?
obj = [[SomeObject alloc] init];
Thanks.
EDIT: Definitely related question that discusses half of my question. The autorelease part of my question is referenced in one of the answers, but has not been confirmed.
So my questions still remain:
Is autorelease a valid alternative in this situation?
Can autorelease be used this way in the init method, or should the instance variable always be set directly in the init method?

The only difference is that in your first example, obj is released immediately (although it was presumably retained by the self.obj setter). The two examples are effectively the same.
Note that going forward, we can rely on ARC to deal with releasing objects at the appropriate time, so you can write:
self.obj = [[SomeObject alloc] init];
and let ARC worry about where to put the release or autorelease.
Update: You seem to be asking how things are different inside an -init method. The two things you need to be aware of are:
When possible, you should access ivars directly in -init and -dealloc methods. The idea is to avoid problems that could occur if your accessors are overridden by a subclass. There are a number of other questions here on SO that address this in greater depth, such as:
Why shouldn't I use Objective C 2.0 accessors in init/dealloc?
If you're creating an object in an -init method and assigning it to an ivar, you probably don't want to release it until a later point, such as -dealloc. So yes, it's fine in an -init method to not release the objects you create (so long as you keep a reference to them), but you'll still balance that +alloc with a -release in -dealloc.

Related

Why is alloc needed in Objective-C object initialization?

I have been going over some tutorials in Objective-C and I am confused when it comes to the command alloc() and how it is used to initialize an object.
The tutorial says to do the following and I am having trouble figuring out why it is necessary.
Change
NSDate *now = [NSDate date];
to
NSDate *now = [[NSDate alloc] init];
Why is this change necessary since the first line works just fine? I guess I am looking for how the two lines differ. Thanks!
There's a simple difference and a deeper one.
The simple answer is that the first method includes an +alloc/-init pair internally—the documentation tells us that it returns a new date object initialized to the current time. Generally, somewhere, somebody has to call +alloc and an -init method of some sort. Sometimes that's you, sometimes a convenience method has been included for you.
The deeper answer about the difference is that +alloc/-init returns an object that is owned by the caller, who is then responsible for calling -release at some point, while convenience constructors that don't start with the words "alloc" or "new" return autoreleased objects that you don't have to release. However, if you are using ARC, this is mostly academic, as the compiler tracks that detail for you.
Break it down:
NSDate is a class. So NSDate alloc is a call to the class method alloc. That's actually inherited from NSObject and acts to create sufficient storage for a new instance of NSDate, then return it for use as an instance.
(instance) init is a call to the instance method init. Prior to calling init the instance you've received is not guaranteed to be in a valid state. Calling init or the relevant initialiser gives the instance the chance to establish itself.
NSDate also choses to supply the class method date. That does the same thing as [[[NSDate alloc] init] autorelease] and is provided as a mere shorthand.
As other posters have commented, there is a semantic difference here — alloc returns an owning reference. So it's the caller's responsibility to release the object later. date returns a non-owning reference. So the caller has no responsibilities. However the modern ARC compiler will deal with releasing things for you. So there's a difference but not one that has any real effect on you.
If your tutorial insists that date is more proper then either it was written before the ARC compiler or was written by someone that prefers to use the old conventions; using date would traditionally communicate that the thing you were creating was for transient use so there is arguably some extra value in the one way versus the other for an experienced developer.
With ARC it doesn't matter as you no longer have to release objects you alloc init.
Without ARC the difference in important:
[NSDate date]
returns an autoreleased object using a class method on NSDate.
[[NSDate alloc] init]
returns a non autoreleased object instance, with a retain count of one.
As in non- ARC, you need to take memory management in your own hands, So, alloc init is better option. So, that you can release it, once not required.
One further point to note, is that autoreleased objects are released when the autorelease pool is.
When you alloc init you know that your object will stay around until you release it (or you leak it because it goes out of scope).
The change is not necessary at all. It doesn't matter if you create object using alloc+init or using convenience methods. Think about them as legacy and convenience methods.

Do I have to release object in Objective-C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Understanding reference counting with Cocoa and Objective-C
I'm little confused with memory leaking - when I have to release object, and when it will be released automatically in iOS, so please help me understood using following code.
I have one method with following while block:
-(void) oneMethod {
NSMutableArray *returnValue = [[[NSMutableArray alloc] init] autorelease];
while(true) {
...
MyObject *myObj = [[MyObject alloc] initWithFrequency:100];
[returnValue addObject:myObj];
[myObj release];
...
}
}
Do I have to call [myObj release] or it will be released automatically in each loop?
Also, do I have to put autorelease in NSMutableArray init call, or it will be automatically released immediately after I return from method?
Thank you!
You should be using ARC - Automatic Reference Counting then you won't need to worry about releasing your allocated objects.
Your code is correct.
I find that as you work more with it you will get used to it. I don't spend much time thinking about it.
Generally, you need to release everything (or autorelease) you make.
Your loop is coded correctly in that its easy on memory, even for large arrays.
The sooner, the better is what I learned. Your example is appropriately releasing each myObj variable once inserted into the array. The array now "owns" the object and the object will exist as long as the array exists, no reason for the variable reference to remain.
ARC does seem to make all this completely unnecessary. I wonder how many developers will even learn this concept in the near future as ARC does it all for you now.
Presumably, you are not using ARC and so, if you did not call [myObj release] it would result in a leak each time through the loop.

Autoreleasing objects created in a thread and passed to another in objective-C

I have a method of an object which creates objects which are then passed to a method of another object in another thread, like this:
MyClass* myClass = [[MyClass alloc] init];
[anotherClass performSelectorOnMainThread:#selector(method) withObject:myClass waitUntilDone:NO];
in method, I immediately retain the object, supposing it will be somehow released by the creator. My question is: how do I make MyClass release that object correctly? Is this the correct way to go?
My solution was to release the object manually in method. I see anyway that the Leak analyzer still recognizes this as a leak and seems it is not what Apple recommends, as the owner has the responsability to release the object.
Can you explain me the correct way to handle this situation? Thanks!
I don't fully understand what you're trying to achieve, but in general:
You shouldn't worry about who and when releases/deallocates the object. Instead, just make sure to retain it when you (a single object or method of yours) start needing it and release it when you stop needing it (or autorelease it, in which case it will be released on the thread on which you called autorelease).
This is exactly the way the performSelectorOnMainThread:withObject:waitUntilDone: works. From the documentation:
This method retains the receiver and the arg parameter until after the selector is performed.
It retains them while it needs them for doing it's job.
In short, the mehod that creates the objects and sends them to another thread should be:
MyClass* myClass = [[MyClass alloc] init]; // retained, will need it for performSelector
[anotherClass performSelectorOnMainThread:#selector(method) withObject:myClass waitUntilDone:NO];
[myClass release]; // no longer needing it.
or
MyClass* myClass = [[[MyClass alloc] init] autorelease]; // will be released automatically, but guaranteed to be retained until this method returns
[anotherClass performSelectorOnMainThread:#selector(method) withObject:myClass waitUntilDone:NO];
The way you have it now is a memory leak.
The receiving method:
if it uses the object only internally, doesn't have to retain it, since performSelector does "until after it is performed" (the method returns).
if it needs it later, it should be assigned to a property which retains it.
Your question is very hard to understand because you talk about this object, that object, another object and use meaningless names like myClass, anotherClass and method. It remains unclear which object you intend to release and which one is reported as leaking.
Anyhow, multi-threading doesn't add any special complexity to reference counting. Certainly, your two object myClass and anotherClass aren't short-lived objects. So if you use autorelease, make sure that the reference counter doesn't go to 0 if all autoreleases have been executed.
It's perfectly okay to release either myClass or anotherClass or both in method.
You don't show a lot of code. But what you show is okay.

Reference on when to release in Objective-C

I'm having a recurring problem in Objective-C. I'm either releasing things too many time, or not enough. or perhaps I'm not retaining them enough...
Can someone point me at a good reference that will give me a rule of thumb on when I need to retain and release?
For example:
I remember reading somewhere that some objects come pre-retained, so I need to release them, but not retain them. Which objects are these?
if I alloc an object and only need it in that method, do I need to release it? retain it?
Obviously, if I retained something, I needtorelease it, but beyond that, I get a bit lost.
The rules are generally pretty simple. If you get an object in one of the following ways:
id obj = [[MyObject alloc] init];
id obj = [myObject retain];
id obj = [myObject copy];
id obj = [myObject mutableCopy];
then you need to release it at some point -- in the same method, or your dealloc method, generally. In other words, balance your calls to alloc, retain, copy, and mutableCopy with a matching release call.
I remember reading somewhere that some objects come pre-retained, so I need to release them, but not retain them. Which objects are these?
This happens rarely. The documentation for the called method should specify that you are responsible for releasing the returned object; otherwise, you should assume you're receiving an autoreleased object.
if I alloc an object and only need it in that method, do I need to release it? retain it?
Yes, you need to release it (but you don't need to retain it). (You can also use one of the convenience methods that return an autoreleased object if you're only going to use it in that method.)
There is one and only one canonical reference: Apple's Memory Management Guide for Cocoa or iPhone.

Memory Management Autorelease vs. Alloc Question

3 correlated questions:
1.Do the code snippets below provide the very same results in terms of memory?
NSBundle *bundle=[[NSBundle alloc] init];
[bundle release];
bundle=nil;
and
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
NSBundle *bundle=[NSBundle mainBundle];
[pool drain];
pool=nil;
bundle=nil;
2.Why in
NSBundle *bundle=[[NSBundle alloc] init];
[bundle release];
the retainCount of bundle is 1, not 0?
3.Which is recommended: always use class methods, or always gain ownership by using alloc?
Thanks.
Yes, those should be equivalent in terms of memory management, from the developer's point of view. The frameworks might be doing something behind the scene to hang on to [NSBundle mainBundle], but that's not your concern.
Ignore retainCount. waves hand That's not the method you're looking for. Once you have relinquished ownership of an object, either by invoking release or autorelease, then it is invalid (bad practice) to send more messages to that object. In your example, you alloc an NSBundle, so you own it. That means it has a +1 retain count (I say +1, because it's relative). When you release the bundle, it now has a "0" retain count, which means you no longer own this object (despite whether or not it may still exist in memory), which means you should not send messages to it, under penalty of stuff blowing up in your face.
What's recommended is to use whatever's appropriate for the situation. If you just need a temporary object, then using a class method that returns an autoreleased object is probably going to be just fine. If you need to be absolutely sure that the object isn't going to go away while you're using it, then you can use an alloc/init approach (or retain an autoreleased object) and then just release it when you're done.
In the second example you will create 1 extra object (the NSAutorealeasePool) and because of that the two are not exactly the same in terms of memory. But after the code runs I believe the memory will return to the same state in both examples. I am not really sure but I believe that in the second example bundle is an autoreleased object, so when the pool is drained it gets released.
I believe that when the object gets dealloc'ed the retainCount isn't changed.
It is usually recommended to avoid class methods when you create a lot of temporary objects because they won't get released until the next AutoreleasePool drain is called (and if you don't have an AutoreleasePool inside your method it won't happen for sure until you return from your method - and maybe even later). Otherwise you should use the one that feels better for you. I personally prefer allocating them. It is also important to remember that if you want the autoreleased object (the one returned from a class method) to stick around even after you return from the function to retain it.