This question already has answers here:
alloc and init what do they actually do
(5 answers)
Closed 9 years ago.
NSDate* now = [[NSDate alloc] init];
Currently learning Objective C and my book doesnt seem to do a good job of explaining this line of code. So, i'm aware that we are declaring a pointer "now" that points to an NSDate object. The message is what seems to be confusing me.
If i'm correct, [NSDate alloc] is allocating some memory for an instance of NSDate, but what is init doing?
You are correct about alloc
It allocates memory for an instance of NSDate
init does what it sounds like. It initializes this newly allocated memory. At this point you don't really need to know what init does internally.
Keep learning and when you get to the topic of creating a custom class or subclass, the role of init will become more clear.
it's very simple ...
NSDate* now = [[NSDate alloc] init];
1.alloc allocates memory for the instance of NSDate i.e now in your code
2.init initializes your instance variable with some default value . if don't use init then your instance may contain some garbage value , to avoid that we usually initialize object with some default value .
Related
I'm still little bit perplexed by pointers and memory management (starting out with ObjC and Cocoa). What got me thinking, is this piece of code:
double seconds = [[NSDate date] timeIntervalSince1970];
This is what I understand:
I get value of float type returned from calling method/message on NSDate class
This value gets stored in variable seconds
What I don't understand is am I creating NSDate object (=instance of class NSDate) at all? Is this object only temporary?
I always thought that the way to create an object and have the object to be persistent (at least until ARC steps in or it is destroyed when function ends) is to create a pointer to it. Maybe like this:
NSDate *now = [NSDate date];
[now timeIntervalSince1970] // get the value
Does this mean that in my original example, there is some unnamed (no variable pointing to it) instance of NSDate created on the heap and once it returns the float value it gets removed from heap?
Does this mean that in my original example, there is some unnamed (no
variable pointing to it) instance of NSDate created on the heap and
once it returns the float value it gets removed from heap?
Yes, that's exactly right.
ARC will remove the object when it goes out of scope.
Even before ARC, the object would be created as autorelease and be released the next time through the event loop (or whenever the nearest autorelease pool was drained).
This question already has answers here:
Difference between [NSMutableArray array] vs [[NSMutableArray alloc] init]
(2 answers)
Closed 9 years ago.
I am new to Obejtive C so im looking at alot of sample code at the time and i noticed that people initialize their NSMutableArray differently.
NSMutableArray *items = [NSMutableArray array];
or
NSMutableArray *items = [[NSMutableArray alloc] init];
In both lines you end up with an NSMutableArray Object.
What is the difference between them or are they exactly the same?
The main difference between these is if you're not using ARC (Automatic Reference Counting). The first one returns a retained and autoreleased object. The second one returns an object that is only retained. So in the first case, you would want to retain it if you wanted to keep it around for longer than the current run loop. In the second case, you would want to release or autorelease it if you didn't want to keep it around.
Now that we have ARC, this changes things. Basically, in ARC code, it doesn't matter which of these you use.
This question already has answers here:
Acceptable ways to release a property
(4 answers)
Closed 8 years ago.
When I create a variable I want to assign to a property I can do the following (assuming the property is #property (nonatomic,retain) UILabel *myLabel;):
UILabel *temp = [[UILabel alloc] init];
self.myLabel = temp;
[temp release];
What would happen in the following scenario where temp is not used?
self.myLabel = [[UILabel alloc] init];
[myLabel release];
This is assuming I would add a [myLabel release]; in dealloc due to the property.
Would this be proper memory management? In the second example does myLabel have a retain count of 2 after the init line?
The second might happen to work, but is incorrect. The first line calls setMyLabel:. That may happen to set an ivar, it may not. It might do all kinds of things (it might make a copy, it might store the information elsewhere, etc). Your second line releases an ivar. If the setter happens to be implemented the way you're assuming, then you will get lucky and it will work. But this is not correct memory management.
The first example is correct. You can also use the autorelease pool to simplify things. Better is to move your code to ARC, which solves all of these problems faster and more easily.
Assigning to a retain property will automatically call retain on the object assigned to (and call release on the previous object). So yes, after
self.myLabel = [[UILabel alloc] init];
[myLabel retainCount] will return 2, one from init and one from assigning the property. So you should either add autorelease to the line above, or call release before the function exits.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Use of alloc init instead of new (Objective-C)
Does any of you use +new of the NSObject to alloc & init the object?
Lets say i got an object C derived from Object B which all are from NSObject. To create an instance of Object C
C newInstanceOfC = [C new]; // This will call the alloc & init of class C.
is this any better than
C newInstanceOfC = [C alloc] init];
other than less things to type. What is good practice?
cheers
Arun
alloc] init] is best practice. In particular, objects have different ways to init, including zero, one or more than one parameter. Using new makes an automatic selection of init, but having init visible can help you troubleshoot some nasty bugs that can happen if you initialise a UI element but forget to set the frame, etc.. You'll get compiler warnings about the use of the init method in some circumstances too.
They are both exactly the same, new is the new way, as that wasn't possible before, but use the one that you like the most.
I usually use new since it is shorter, although in several cases you can't since you usually want to do something like:
[[myObject] alloc] initWith...];
I've run into some unfamiliar Objective-c memory management code. What is the difference between:
// no property declared for myMemberVariable in interface
id oldID = myMemberVariable;
myMemberVariable = [MyMemberVariable alloc] init];
[oldID release];
and:
// (nonatomic, retain) property is declared for myMemberVariable in interface
self.myMemberVariable = [[MyMemberVariable alloc] init];
Thanks!
The second is technically incorrect, but the first probably stems from someone yet to embrace Objective-C 2.0 property syntax. It was added relatively recently if you're a long-time OS X developer (or an even-longer-time NextStep/OS X developer), so you do see people not using it without gaining any benefit or detriment by not doing so.
So the first is basically the same as:
[myMemberVariable release];
myMemberVariable = [[MyMemberVariable alloc] init];
Given that you have a 'retain' property, the correct version with the setter should be:
// this'll be retained by the setter, so we don't want to own what we pass in
self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease];
In the first example, you've got an instance variable. In the second, a property with auto memory management attributes (as indicated by the retain).
In the first example, you're allocating an object, assigning it to an instance variable, then releasing it. It also appears that you're also leaking the object that was previously assigned to it since you don't explicitly release it. (Maybe it's autoreleased, can't tell here).
In the second example, you're allocating an object, and assigning it to a property that is retaining it. This means you're going to leak it unless you explicitly release/autorelease it.
self.myMemberVariable = [[[MyMemberVariable alloc] init] autorelease];
or
MyMemberVariable *m = [[MyMemberVariable alloc] init];
self.myMemberVariable = m;
[m release];
It's much better to use properties as you get (most) memory management for free. For example, you won't have to worry about freeing a reference before assigning a new one.
The first form does not use properties. I don't see a good reason not to do:
[myMemberVariable release];
myMemberVariable = [[MyClass alloc] init];
Since the old value is definitely not the same as the new one, so there is no chance any old value is released before it can be retained again.
Properties have the advantage that, in newer compilers, they are synthesized by the compiler and simply do the right thing, i.e. they know how to retain the new and release the old value, if the type is one that must be retained or copied. This is not necessary for types like int, float, etc., since these are simple value types.
In other words, if you use dot notation, either on self or on some other object, you access the property and in fact call either the getter or setter methods, depending on the direction of assignment.
If you access the ivar (member variable) directly, you don't have the protection from the property and have to code retain/release yourself.
You can also write your own setters and getters, and then you'll also have to take care of memory management, where it applies. It does, however, give you more flexibility. You could log items, check the validity of the input, update internal state variables, etc.