In Objective-C, How to initialize NSMutableArray with objects in another NSMutableArray using tableView reference - objective-c

Developing for MacOS, I have an NSMutableArray namesArray[] that contains 3 String objects.
namesArray[] is represented in a tableView, where user can select multiple cells, each cell represents a single object.
I am trying to initialize a second NSMutableArray savedNamesArray[], and add objects from the original namesArray[] based on the selected cells in my tableView using this method:
NSMutableArray *savedNamesArray = [[NSMutableArray alloc] initWithObjects:[namesArray objectsAtIndexes:[_tableView selectedRowIndexes]], nil];
The problem is, no matter how many objects I select, only one gets added to the new NSMutableArray. Any suggestions?

You're adding one object, an array, to savedNamesArray. Use initWithArray: instead.
NSMutableArray *savedNamesArray = [[NSMutableArray alloc] initWithArray:[namesArray objectsAtIndexes:[_tableView selectedRowIndexes]]];

Related

Updating values on NSArray

I'v run into such problem. I need to update the values in my NSArray. And don't know a way to do it. Here's my array
NSArray *arrayWithInfo = [[NSArray alloc] initWithObjects:AMLocalizedString(#"Status", nil),AMLocalizedString(#"Call", nil),AMLocalizedString(#"Location", nil),AMLocalizedString(#"Control", nil),AMLocalizedString(#"Sim", nil),AMLocalizedString(#"Object", nil),AMLocalizedString(#"Info", nil),nil];
self.dataArray = arrayWithInfo;
[arrayWithInfo release];
To be more specific I have tableview initialized with this array. There is a possibility for user to use different localized strings, so I have to update it. By using [tableview reloadData]; i'v got the table to update, but the values in NSArray stay the same as they were initialized in first place.
So how to make array look up at the strings once again and get their new values?
Use NSMutableArray instead of NSArray
NSMutableArray (and all other classes with Mutable in the name) can be modified.
You should be using an NSMutableArray. Doing so will allow you to change its values after instantiation.
Your array doesn't need to be mutable here as the array seems to be all or nothing. You dont mention the requirement to delete some objects and not others. NSMutableArray isn't needed. You want to write a lazy loading getter method for the array which reinstantiates it if the array doesnt exist.
-(NSArray *)dataArray{
if (_dataArray){
return _dataArray;
}
_dataArray = NSArray *arrayWithInfo = [[NSArray alloc] initWithObjects:AMLocalizedString(#"Status", nil),AMLocalizedString(#"Call", nil),AMLocalizedString(#"Location", nil),AMLocalizedString(#"Control", nil),AMLocalizedString(#"Sim", nil),AMLocalizedString(#"Object", nil),AMLocalizedString(#"Info", nil),nil];
return _dataArray;
}
Then when you want to reload the tableView
self.dataArray = nil;
[tableView reloadData];
this destroys the old array, forcing it to be remade but with the new localisation.
EDIT:
The issue is the array isn't storing the statement AMLocalizedString(#"Status", nil) its storing the result of that statement, which is the localised string itself. There is no way to make the array re-evaluate that statement without either re-creating the whole array again or using an NSMutableArray and changing all the objects. The lazy loading getter method is more in the objective-c style.
You need to use the NSMutableArray. The NSArray is immutable.

mutable copy copies by reference, not value?

Apparently mutableCopy copies by reference, not value. Ie if I do this:
NSMutableArray arrayA = [arrayB mutableCopy];
then change values of arrayB, then arrayA's values will also be changed.
I think Java has a clone() method to copy by value.. is there an equivalent in objective c?
The mutableCopy method performs “shallow” copy. Each element of arrayA is a reference to an object that is also in arrayB. If you add elements to arrayA (or remove elements), arrayB will be unchanged, and vice versa. But since the elements of arrayA and arrayB reference the same objects, a change to one of those objects “shows up” in both arrays.
If you want a one-level deep copy of arrayB, you can do this:
NSMutableArray *arrayA = [[NSMutableArray alloc] initWithArray:arrayB copyItems:YES];
That will have this effect:
NSMutableArray *arrayA = [[NSMutableArray alloc] init];
for (id element in arrayB) {
[arrayA addObject:[element copy]]; //copies immutable objects to new array
}
To deep copy an array you need to use:
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray: oldArray copyItems:YES];
This performs a copyWithZone: on each object in the array
The regular [NSMutableArray copy] method will, as per Apple's documentation, return a "functionally independent object with values identical to the original at the time the copy was made." You should probably just use that.
To be totally sure that it is mutable, use [[NSMutableArray alloc] initWithArray:[otherArray copy]].

unable to store an image in an NSMutableArray

I am trying to save an image in an NSMutable array and it is not working
here is what I am doing
[imagesList addObject:[UIImage imageNamed:#"b.png"]];
after executing this line I noticed that the number of objects remains 0
any reason ?
Thanks
I repeate this code in several areas :
Globally I declare :
NSMutableArray *imagesList;
NSUserDefaults *imagesHistory;
in my viewdidload method I write:
imagesHistory=[NSUserDefaults standardUserDefaults]; //imagesHistory is created globallt as NSUserDefault imagesHistory
[imagesHistory setObject:imagesList forKey:#"images history"];
UIImage *image;
image=[UIImage imageNamed:#"b.png"];
[imagesList addObject:image];
imagesHistory=[NSUserDefaults standardUserDefaults];
[imagesHistory setObject:imagesList forKey:#"images history"];
and in the didFinishLaunchingWithOptions I write : (even though I don t need to do it when I am adding strings ...)
imagesList = [[NSMutableArray alloc] init];
Regardless of whether it is a global variable or not, you still need to call alloc and init SOMEWHERE for the object. If you intend to use it throughout your app, then appDidFinishLaunchingWithOptions is a decent place to add this call:
imagesList = [[NSMutableArray alloc] init];
Is your empty array being retained? If you're not using Automatic Reference Counting, there's a good chance you're initializing the array with the following
imagesList = [[NSMutableArray alloc] init];
but it's not being retained. You'll want to retain the empty array so it gets appended to further on in your code.
imagesList = [[[NSMutableArray alloc] init] retain];
Just don't forget to release the array when you're all done with it, in viewDidUnload or wherever is appropriate.
You're allocating/initing imagesList AFTER you try to add an object. You need to alloc/init imageList before you add anything to it.
To make sure it's there, try something like this:
if (!imagelist) imageList = [[NSMutableArray alloc] init];
If it exists, and you're still having this problem, it's possible that you're allocating/initing a new NSMutableArray and assigning it to imageList after you've added the object. This means the old array would be discarded and you'd be left with a new array with zero items.
try UIImageView *image;
image=[UIImage imageNamed:#"b.png"];
also, in #property(nonatomic,retain) use 'strong' instead of 'retain'

Handling NSArray and NSMutableArray

I'm working with the MKMapView and I'm using some arrays to handle the title of points on the map
NSString *mapTitles = #"title1^^title2^^title3^^title4";//this data changes between views
NSArray * titlesArray = [mapTitles componentsSeparatedByString: #"^^"];
NSMutableArray * maptitle = [NSMutableArray arrayWithCapacity:[titlesArray count]];
[maptitle addObjectsFromArray:titlesArray];
When a user navigates to another page I want to clear the NSMutableArray so that when they come back to the map I can refresh it with new data. However as the NSMutableArray is getting populated by an NSArray which I can't clear, how do I ensure that the NSMutableArray only gets populated by new data as opposed to something that the NSArray may have kept from the previous view?.
Is it simply a case of releasing the NSArray, for example in viewWillDisappear?
Thanks
You can still clear the mutable array itself:
[mapTitle removeAllObjects];
You shouldn't release the titlesArray because it's autoreleased.

IOS: fill a NSMutableArray with some NSMutableArray

In my project I must fill an NSMutableArray with some NSMutable array, my code is:
This is a method
-(void) fill {
[smallArray removeAllObjects]; //when I call this method I delete every object inside smallArray
for {
//in this for I fill with some object a NSMutableArray that I called "smallArray"
[smallArray addObject:object];
}
//outside this for I have my NSMutable bigArray that I must fill with smallArray
[bigArray = ?????];
How can I fill this bigArray?
Unlesss I'm missing something, simply use the addObject: method (as you're already doing for the small array), supplying the smallArray to add.
i.e.: [bigArray addObject:smallArray];
If however you just want to add the objects from smallArray into the bigArray, then you could use the addObjectsFromArray: method...
[bigArray addObjectsFromArray:smallArray];
...which will append the objects after any existing ones within bigArray. For more information, check out the relevant section of the NSMutableArray Class Reference documentation.
If i understang correctly you must have an array that contains other arrays?
[bigArray addObject:smallArray];
Then you can access the array like this
NSMutableArray * arrayfromArray =[bigArray objectAtIndex: someIndex];