Initialization of an NSMutableArray with array or alloc init [duplicate] - objective-c

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.

Related

What is the point of nil when init NSArray? [duplicate]

This question already has answers here:
Why does NSArray arrayWithObjects require a terminating nil?
(6 answers)
Closed 7 years ago.
I'm new to objective-C. I'm just read some of article, and I saw that when init Array or Set, the writer do something like:
NSArray *list=[[NSArray alloc] initWithObjects:#"Andy",#"Erik",#"Aaron",nil];
I'm try to not use nil and nothing change, so, what is the point of nil when init an array or a set?
That's how the 'method' 'knows' that you've given it the last item
in the list so it can know for sure when it reaches the end of the
arguments for the method.
NSArray *listdemo = [[NSArray alloc] initWithObjects:#"Andy",#"Erik",#"Aaron",nil];
The method is iterating
through the list until it finds nil. If it doesn't, it runs off the
end and Bad Things happen.

What is the "init" call doing in this line of code? [duplicate]

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 .

initWith vs arrayWith in objC?

What are the pros and cons of creating an array (or any other collection using its respective factory method) with
[[NSArray alloc] init]
vs
[NSArray array]
in objective C? It seems like the latter factory method allows us to not worry about memory management, so I was curious if there's any point in ever using alloc + init, though I'm now more interested in all the differences between these two, and why one would choose one over the other.
Prior to ARC there was a critical difference. The alloc/init case returned a retained object, while the array case returned an autoreleased object.
With ARC the difference is less important. Probably the first case is a hair more efficient, but in most scenarios they are interchangeable.
In the first one, you have the ownership of array object & you have to release them.
NSMutableArray* p = [[NSMutableArray alloc] init];
[p release];
& last one you dont need to release as you don't have the ownership of array object.
NSMutableArray* p = [NSMutableArray]; //this is autoreleased
If you call release in this, then it will crash your application.

Memory management for unnamed variable [duplicate]

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.

Memory allocation for an array of Objects - Is my understanding valid?

I have a question regarding memory allocation for Objects in an array. I am looking to create an array of Objects, but at compile time, I have no way of knowing how many objects I will need, and thus don't want to reserve more memory than needed.
What I would like to do is allocate the memory as needed. The way I would like to do this is when the user clicks an "Add" button, the array is increased by one additional object and the needed memory for the new object is allocated.
In my novice understanding of Objective C (I was a professional programmer about 20 years ago, and have only recently begun to write code again) I have come up with the following code segments:
First, I declared my object:
NSObject *myObject[1000]; // a maximum number of objects.
Then, when the user clicks an Add button it runs a method with the allocation code: (note: the variable i starts out at a value of 1 and is increased each time the Add button is clicked)
++i
myObject[i] = [[NSObject alloc] init];
Thus, I'm hoping to only allocate the memory for the objects actually needed, rather than all 1000 array objects immediately.
Am I interpreting this correctly? In other words, am I correct in my interpretation that the number of arrayed elements stated in the declaration is the MAXIMUM possible number of array elements, not how much memory is allocated at that moment? It this is correct, then theoretically, the declaration:
NSObject *myObject[10000];
Wouldn't pull any more memory than the declaration:
NSObject *myObject[5];
Can someone confirm that I'm understanding this process correctly, enlighten me if I've got this mixed up in my mind. :)
Thanks!
Why not use NSMutableArray? You can initWithCapacity or simply allocate with [NSMutableArray array]. It will grow and shrink as you add and remove objects. For example:
NSMutableArray *array = [NSMutableArray array];
NSObject *object = [[NSObject alloc] init];
[array addObject:object]; // array has one object
[array removeObjectAtIndex:0]; // array is back to 0 objects
// remember to relinquish ownership of your objects if you alloc them
// the NSMutable array was autoreleased but the NSObject was not
[object release];
Your understanding is mostly correct. When you do:
NSObject *myObject[1000];
You immediately allocate storage for 1000 pointers to NSObject instances. The NSObject instances themselves are not allocated until you do [[NSObject alloc] init].
However, doing NSObject *myObject[10000] will consume more space than doing NSObject *myObject[5], because 10,000 pointers certainly require more memory to represent than 5 pointers.
Remember that both things consume space, the pointer to the NSObject, and the NSObject instance itself, though in practice the space consumed by an NSObject instance will be significantly larger than the 4 bytes consumed by the pointer that refers to it.
Anyhow, perhaps more importantly, there is a better way to manage dynamic object allocation in Cocoa. Use the built-in NSMutableArray class. Like:
NSMutableArray* objects = [[NSMutableArray alloc] init];
[objects addObject: [[[NSObject alloc] init] autorelease]];