I am curious on what happen if I have code like this.
NSArray* myArray = [NSArray alloc]initWithObjects:#"a", #"b", #"c", nil];
[myArray autorelease];
myArray = [otherArray copy];
autorelease would mark the memory to be released at the end of current event loop.
Does that mean [otherArray copy] is released at the end of event loop?
No. When you autorelease objects, the objects are added to the autorelease pool, not the pointer to those objects. You're autoreleasing an array, if you copy another array into that pointer, it will not be affected. You should be using ARC anyway, and not using auto/release.
Related
There seem to be different methods of instantiating NSArrays (same for NSDictionary and some others).
I know:
[NSArray array]
[NSArray new]
#[]
[[NSArray alloc] init]
For readability reasons I usually stick with [NSArray array], but what is the difference between all those, do they all really do the same?
Results are same for all of them, you get a new empty immutable array. These methods have different memory management implications though. ARC makes no difference in the end, but before ARC you would have to use the right version or send appropriate retain, release or autorelease messages.
[NSArray new], [[NSArray alloc] init] return an array with retain count is 1. Before ARC you would have to release or autorelease that array or you'd leak memory.
[NSArray array], #[] return an already autoreleased array (retain count is 0). If you want it to stick around without ARC you'd have to manually retain it or it would be deallocated when the current autorelease pool gets popped.
[NSArray array] : Create and return an empty array
[NSArray new] : alloc, init and return a NSArray object
#[] : Same as 1.
[[NSArray alloc] init] : Same as 2.
Different between [NSArray array] and [[NSArray alloc] init] is if there are non-ARC:
[NSArray array] is an autorelease object. You have to call retain if you want to keep it. E.g when you return an array.
[[NSArray alloc] init] is an retained object. So you don't have to call retain more if you want keep it.
With ARC, they are same.
If I've to reinitialize a NSArray with others values, is it right to do this?
NSArray *array = [[NSArray alloc] initWithObjects:obj1, obj2, nil];
// ...
// some code
// ...
array = [[NSArray alloc] initWithObjects:obj3, obj4, nil];
thanks
Yes this is absolutely right. The new object is completely different than the previous. The object pointer now points to a new object and the old one will be released, since you are using ARC.
It is not exactly the same as reinitializing because you throw away the object and getting a new, but NSArray is immutable so this is the only way to "reinitialize" it.
Your code does not re-initialze an NSArray. It just assigns a new object to the variable array. That's fine.
I thinks this code may help you. At least, I thing this may be a suitable solution, especially if you are using ARC:
NSObject *obj1 = [NSNull null];
NSObject *obj2 = [NSNull null];
NSMutableArray *arrayObj = [NSMutableArray arrayWithObjects:obj1, obj2, nil];
[arrayObj removeAllObjects];
arrayObj = [NSMutableArray arrayWithObjects:obj1, obj2, nil];
I hope it helps you :)
you can reinitialize NSArray with same name ,you will not get any error or warning but the latest objects gets replaced with previous objects.The previous objects overwrites. For this you have to use ARC otherwise memory problem will occurs.
What is the difference between
NSMutableArray* p = [[NSMutableArray alloc] initWithObjects:...]
and
NSMutableArray* p = [NSMutableArray arrayWithObjects:...]
In the first one, you have the ownership of array object & you have to release them.
NSMutableArray* p = [[NSMutableArray alloc] initWithObjects:...];
[p release];
& last one you dont need to release as you don't have the ownership of array object.
NSMutableArray* p = [NSMutableArray arrayWithObjects:...]; //this is autoreleased
If you call release in this, then it will crash your application.
[NSMutableArray arrayWithObjects:] is the same as [[[NSMutableArray alloc] initWithObjects:] autorelease]
In practice, there is no difference if you're on ARC.
The latter basically is just a shorthand for [[NSMutableArray alloc] initWithObjects: ...], except the returned array is autoreleased (which is important if you're still doing manual reference counting).
What I think the difference is that: initWithObjects is a instance method, and arrayWithObject is a class method.
There seem to be some memory leaks in the following loop:
NSMutableArray *array1 = [[NSMutableArray alloc] init];
for(SomeClass *someObject in array2){ //has already been populated;
if (someObject.field == desiredValue){
[array1 addObject:someObject];
}
}
//EDIT:
//use array1 for very secret operations
[array1 release];
Any ideas why?
Are you releasing all your retained properties in SomeClass of yours? Make sure in dealloc release all retained properties.. Make sure your SomeClass is leak free..
In my code, I must to store an array inside another array:
What's the best way?
first:
NSArray *arrayTemp = myArray;
second:
NSMutableArray *arrayTemp = [[NSMutableArray alloc]init];
[arrayTemp addObjectsFromArray:myArray];
...instruction....
[arrayTemp release];
By doing arrayTemp = myArray, you declare arrayTemp as a new pointer to your existing array myArray. That's not a copy (if you put X in myArray[42], arrayTemp[42] will also be X).
The second variant looks like you're doing a copy of your array, but still the array's values are copied by reference (by pointer), when you seem to need a copy "by value".
What you should try is simply:
NSArray *arrayCopy = [myArray copy];
Beware: from a memory management point of view, this is equivalent to a retain or a alloc/init: you should release your arrayCopy after use.