NSMutableArray initializing from viewDidLoad - ios

arrayOfElements = [NSMutableArray arrayWithArray:[someObj getArray]];
and
arrayOfElements = [[NSMutableArray alloc] init];
arrayOfElements = [someObj getArray];
What's the difference?
The first arrayOfElements does not seem to lose its objects when it returns count in numberOfRowsInSection:(NSInteger)section, but the second one does. I get EXC_BAD_ACCESS when I do it the second way.
EDIT:
Can I suppose now that this is the best way,
arrayOfElements = [[NSMutableArray alloc] initWithArray:[someObj getArray]];
because I am initializing an array with the contents of whatever will be autorelease'd, and I now have a fully independent array in the current class, that is viewDidLoad, oops sorry, ViewController.

This line creates an NSMutableArray from an existing array
arrayOfElements = [NSMutableArray arrayWithArray:[someObj getArray]];
This combination first creates an NSMutableArray and then instantly discards it replacing it with what is returned by [someObj getArray]
arrayOfElements = [[NSMutableArray alloc] init]; // Create new NSMutableArray
arrayOfElements = [someObj getArray]; // Throw away the newly created array and replace with the result of [someObj getArray]
If you are not using ARC then it is purely by luck that either would work.
In both cases arrayOfElements is being assigned an autorelease'd object - which will be cleared soon (most likely the next runloop). It is only by chance that nothing else has been written over this point of memory which allows one of your implementations to still work.
If you are not using ARC then really you should update your project to be using it will handle a lot of cases like this for you.
You should definitely be using properties (not bare ivars) as this will help reduce memory issues (for non-ARC) and give a more consistent interface to your code.
In your header (or class extension) declare the property like this
#property (nonatomic, strong) NSMutableArray *arrayOfElements;
Now for ARC you can simple do
[self setArrayOfElements:[[someObj getArray] mutableCopy];
for non-ARC you can do
NSMutableArray *array = [[someObj getArray] mutableCopy];
[self setArrayOfElements:array];
[array release]; array = nil;
Also note that getArray is a bad method name.
The use of “get” is unnecessary, unless one or more values are returned indirectly.
Coding Guidelines

When you are adding objects to mutable array from another array, try this:
[arrayOfElements addObjectsFromArray: [someObj getArray]];

If you're not using ARC, you need to make sure its retained.
if (arrayOfElements) {
[arrayOfElements release];
}
arrayOfElements = [[NSMutableArray alloc] initWithArray:[someObj getArray]];

Related

Objective C removeObjectsAtIndexes desire cleaner coding

I would like to create a shorter and more elegant version of some working code.
FYI I have to add an element to an existing array, and then remove one, and repeat. (unfortunately I can't add more than one element and then remove more than one).
Working code:
NSMutableArray *destinationArray;
destinationArray = [[NSMutableArray alloc] init];
NSMutableArray *originArray = [[NSMutableArray alloc]init];
// Copy one specific array element from originArray to destinationArray
// Note: assume originArray and destinationArray populated at this point
int originIndex = var1-var2+1;
[destinationArray addObject:originArray[originIndex]];
// Remove one specific array element from destinationArray
[destinationIndex removeAllIndexes]; // clear index if used previously
[destinationIndex addIndex:var3-var4-1];
[destinationArray removeObjectsAtIndexes:destinationIndex];
I would prefer some version of the following:
[destinationArray addObject:originArray[var1-var2+1]];
[destinationArray removeObjectsAtIndexes:[var3-var4-1]];
Is there a way to make this shorter version work? (gives expected identifier error)
Thanks much for your help...
Why not do this:
NSMutableArray *destinationArray = [[NSMutableArray alloc] init];
NSMutableArray *originArray = [[NSMutableArray alloc]init];
// somewhere in here objects are added to "originArray"
[destinationArray addObject:originArray[var1-var2+1]];
[destinationArray removeObjectAtIndex:var3-var4-1];

How does this NSMutableArray alloc&init work?

I see a new kind of alloc&init NSMutableArray way in one project. It's like this A
NSMutableArray *array = [#[] mutableCopy]; and this works well, and i want to try whether its possible to use BNSMutableArray *array = [NSMutableArray mutableCopy]; it build succeeded, but got this error when used: +[NSMutableArray addObject:]: unrecognized selector sent to class 0x38bedc2c
Now i want to know how does A work? and why B is wrong? A is better than normal alloc&init?
Any help will be appreciated.
mutableCopy is an instance method declared in NSObject class. It is called on any instance to create a mutable copy of it.
In first case #[] will create an autoreleased NSArray instance on which calling mutableCopy will create NSMutableArray instance.
In second case calling mutableCopy on the class is incorrect because it is not meant to be called that way. This will get compiled but will cause exception at runtime.
Hope that helps!
In the first case, you're first initializing an empty NSArray instance; think of #[] as equivalent to [[NSArray alloc] init]. Therefore you're sending mutableCopy to a correct instance, so it works fine.
In the second case, you're sending the message to a class (as opposed to an instance of it), which doesn't make much sense, because the addObject message can only be sent to an instance, not the class itself.
#[] means an NSArray with no object. It returns an NSArray, and then its mutableCopy is copied to array.
+[NSMutableArray addObject:] is invalid as addObject is an instance method and you are trying to use it as class method.
Even NSMutableArray *array = [NSMutableArray mutableCopy]; is incorrect!!! As nothing is created, it is not been allocated and inited. If you log the array, it will only print the string NSMutableArray. Also you can't use array to addObject and other operations.
You should use NSMutableArray *array = [NSMutableArray array];
The first one is lazy typing.
You should avoid it.
It creates an empty NSArray from the array literal syntax and the creates a mutable copy.
That's saving a little typing by creating an unnecessary array.
You should just use
[NSMutableArray new]
Or
[[NSMutableArray alloc] init]
Or if possible because you know the initial capacity in advance
[[NSMutableArray alloc] initWithCapacity:someNSUIntegerValue]
Anything else above is laziness.
Only use mutableCopy when you are actually copying some content.

reinitialize a NSArray

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.

iOS: Difference between NSMutableArray alloc/init and arrayWithObjects:

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.

Anything in iPhone that resembles Android ArrayList

I am from android background and I just started working on iPhone
I want to perform this operation in iPhone as I do in Android.
ArrayList<String> aa = new ArrayList<String>();
public void fillArray(String s)
{
aa.add(s);
}
As Binyamin Sharet suggest you have to use NSMutableArray. This class allows you to create a dynamic array. You can perform addition or deletion. On the contrary NSArray is a immutable version of it. You cannot add or delete objects to a NSArray once created.
The same distinction can be applied to NSDictionary and NSMutableDictionary (and other).
Here a simple example.
NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:#"first string"];
[arr addObject:#"second string"];
An important aspect of NSMutableArray (the same could be applied to other class) is the memory management one. When you add an object to a NSMutableArray it retains objects added to it. So, if you NOT use ARC you have to deal with this aspect.
NSMutableArray* arr = [[NSMutableArray alloc] init];
id obj = [[NSObject alloc] init]; // a general object
[arr addObject:obj];
[obj release];
For further info I suggest you to read about NSMutableArray class reference.
Hope it helps.

Resources