Issue related with modifying the value in an NSMutablearray - ipad

I am facing an issue with the values in NSMutablearray. I have two NSMutablearray, both are holding the same content using mutablecopy. The issue is that when I modify a value in one array, the corresponding value in the second array also get modified. How to resolove this. Please help me.

mutableCopy copies by reference, not value. So, any change to one of those objects affects for both arrays.
You could realize different methods to overcome this situation.
// first method
nameArray2 = [NSMutableArray new];
[nameArray2 addObjectsFromArray:nameArray1];
// second method
nameArray2 = [[NSMutableArray alloc] initWithArray:nameArray1 copyItems:YES];
Best regards.

Related

Avoid overriding data in NSMutableDictionary

I would like to add multiple dictionary to NSMutableDictionary.
NSDictionary<NSString*,id<MGLAnnotation>>* feature = #{ localRef : pointAnnotation };
[self.selectedFeatures setDictionary:feature];
I have initialised selectedFeatures NSMutableDictionary in ViewDidLoad of my view controller. I have written these above two lines of code in one function and that function will be called many times and the value of feature will always changing. I want to add those multiple feature to my selectedFeatures NSMUtableDictionary. But setDictionary just overridden the previous values. Please help me to solve my problem.
I guess your self.selectedFeatures is an NSMutableDictionary. If you just want to add the feature dictionary to the self.selectedFeatures, then you can use the method [NSMutableDictionary addEntriesFromDictionary:].
Change this:
[self.selectedFeatures setDictionary:feature];
to this:
[self.selectedFeatures addEntriesFromDictionary:feature];

How to maintain the order of key added in NSMutableDictionary

I didn't knew this at first place, I thought that the key/value pair I am adding to my dictionary will be in the same order when I try to retrieve it back...
Now here is my question -
I have a ViewController which I have made as singleton, inside this VC I have defined:
#property (nonatomic) NSMutableDictionary *dictionary;
Now I try accessing this dictionary from various other classes and set its contents via:
[[[ViewController sharedViewController] dictionary] setValue:[NSNumber numberWithBOOL:NO] forKey:#"xx"] , yy ,zz and so on
I have my delegates implemented which would hit for a particular key(xx,yy,zz and so on). Now whenever a particular delegate method is hit I need to update my dictionary with same key but [NSNumber numberWithBOOL:YES] which is happening .. but the order in which I added the items in dictionary is not maintained ... How can I achieve this?? I need to maintain the order in the same way in which I have added my items to the dictionary at first place??
Can someone please help me out??
As pointed, you should use NSArray to have your values ordered. You can also use some 3rd party APIs like: M13OrderedDictionary or others, however, that's not a pretty solution.
Obviously, the desired solution is to create your own object or struct and keep an array of those objects/structs.
NSDictionary is just a mapping between keys and values that has no defined order. If you try to iterate over the keys, you may or may not get them back in the same order you added them, and you should never depend on the ordering of the keys when iterating over them.
One thing you could do is create an NSArray that contains the keys in the order you want them. Then you can iterate over the keys in the array and get the values from the NSDictionary in the order you wanted. The combination of these two basically gives you a sorted key NSDictionary.
Another thing you could do is to just use an NSArray to stores the values, unless the keys that you're using matter as well. But if all you're trying to do is get the values in a certain order, then I would say NSArray should work fine.
You can make a copy of key by using the following code:
NSArray *allKeys = [dictionary allKeys];
Then, the keys all saved in order and you can access particular value by getting specific key in allKeys array and retrieving it by using dictionary[allKeys[2]].

How to sort UITableView headers according to declaration order

So I have a little problem here, I think I made my point clear in the title of this post. I want to sort UITableView headers according to the order I declared them in code. I tried surfing the net already but I can't find any solution.
I think one from here can help. Thanks in advance!
EDIT: This is my code to of the table view contents
NSDictionary *temp = [[NSDictionary alloc]initWithObjectsAndKeys:accSettingsOpts, #"Account",notifSettingsOpts,#"Notifications",aboutOpts,#"About",logoutOpt,#"Sign Out",nil];
I want to display the table view sorted by
-Account
-Notifications
-About
-Sign Out
But it displays as
-About
-Account
-Notifications
-Sign Out
EDIT: This is how the problem is addressed.
Based from the answer provided in which I accepted below, I modified it as
#interface myClass ()
NSArray *headerArr;
#end
at viewDidload I added
headerArr = [[NSArray alloc]initWithObjects:#"Account",#"Notifications",#"About",#"Sign Out", nil];
and lastly...
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [headerArr objectAtIndex:section];
}
Thanks for the help guys. I didn't imagine that it's just that simple.
A dictionary is an unordered collection. If you store your items in a dictionary, the order in which you defined them is not saved anywhere.
Table views are an inherently ordered list of objects. Therefore a dictionary is not suitable as a way of storing the items for a table view. An array, however, makes a natural data source for a table view.
Use an array rather than a dictionary. It's as simple as that. You can use an array of dictionaries, or an array of some other data objects, and then write your cellForRowAtIndexPath method to extract the data from your model (array elements) and install the values in the cell.
The reason the order is different from the declaration order is that NSDictionary is unordered: it is sorted based on the hash code of your strings, which is rather arbitrary.
To force a particular order, use a container with a fixed order, such as NSArray. For example, you can store your accSettingsOpts, notifSettingsOpts, and so on, in a single array, add a header property to the Opts class, and pull that property to set section headers in your UITableView.

NSMutableArray remove Object is cloning another object in the Array

I have an strange error after removing an object in a NSMutableArray.
If i remove an object with
[Array removeObjectAtIndex:2];
the array changed to this:
why are there now 2 ContactViewControllers??
lldb lies sometimes. It gets confused and will display the incorrect information. Try doing
po Array
you should see the correct array contents then.

Sorting NSArray on two properties - int and date

note from N00B land again. I have read lots about sorting arrays - wanted to try the block method, but haven't wrapped my head around it. Instead, I opted for the descriptors method. I read this Sort NSArray of custom objects by their NSDate properties and this How to sort an NSMutableArray with custom objects in it? amongst oodles and oodles of others. In my code I did this:
NSString *lastHighScore = #"_highScore";
NSString *dateScoreCreated = #"_dateCreated";
NSSortDescriptor *highScoreDescriptor = [[[NSSortDescriptor alloc]
initWithKey:lastHighScore
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSSortDescriptor *dateScoreCreatedDescriptor = [[[NSSortDescriptor alloc]
initWithKey:dateScoreCreated
ascending:NO
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *descriptors = [NSArray arrayWithObjects:highScoreDescriptor,
dateScoreCreatedDescriptor, nil];
NSArray *sortedArray = [[[FlipHighScoreStore sharedStore] allHighScores] sortedArrayUsingDescriptors:descriptors];
Sadly, I am getting an error to begin with - initializer element is not a compile-time element. I looked this up and tried setting NSSortDescriptor *highScoreDescriptor = nil but then I get a warning saying that highScoreDescriptor "Type Specifier Missing, default to int" which in this case is ok, but is not so ok for the Date object in the next descriptor. (Turns out I am also getting an error saying that I am redefining highSoreDescriptor with a different type.)
Also, is there a list somewhere of what selectors are available? I doubt that localizedCaseInsensitiveCompare: is what I want to use since the first property "_highScore" is an int and the second "_dateCreated" is a date. I read somewhere that the default is "compare" so can I just put "compare:"? (Found one answer, I think - I can use (intValue) for the first descriptor:
selector:#selector(intValue)] autorelease];
More reading makes me think that I can do away with the selector line entirely for the date sort. Is that correct?
Lastly, if I say ascending:NO is that the same as descending? I would guess that it is, but one never knows with programming, does one?
Do I wrap all of this code in its own method? Or can I (until later) just plunk it in the code where I am laying out the table?
This project is not ARC.
To answer my own question, with a little help from a friend, I was basically doing two things wrong. First, I was writing the code outside of a method - which is why I was getting all of the errors about initializer elements. I guess I was very tired when I was adding this.
As for the actual sorting, I deleted the selector option from the descriptor description and the sorting actually happened!
Lastly, yes, ascending:NO is equal to descending.
The last bit, will have to wait until I a ready to tackle more refactoring of the application.

Resources