Mutating method send to immutable object - iphone

This the snippet of code where I get an error:
//sourceArray is a NSMutablearray
NSMutableDictionary *dayOfWeekDictionary= [sourceArray objectAtIndex:indexpath.row];
[dayOfWeekDictionary setObject:[NSNumber numberWithBool:YES] forKey:#"isSelected"];//line 2
What I’ve come to know from googling is that there is some stuff in assigning immutable object into mutable object.
I get an error at line 2. Any suggestions?

If [sourceArray objectAtIndex:indexpath.row] returns an immutable dictionary, simply assigning it to a variable of type NSMutableDictionary * doesn’t automatically convert it to a mutable dictionary. You could write this instead:
NSMutableDictionary *dayOfWeekDictionary= [NSMutableDictionary dictionaryWithDictionary:[sourceArray objectAtIndex:indexpath.row]];
By using +[NSMutableDictionary dictionaryWithDictionary:], you get a mutable dictionary based on another dictionary (which can be either mutable or immutable). Note that you do not own this dictionary, hence you don’t have to release it. Also note that this is not the same dictionary object as the one stored in the array. If you need both the array and dayOfWeekDictionary to be the same dictionary, then you should add a mutable dictionary to the array.

Are you sure there is an instance of NSMutableDictionary in [sourceArray objectAtIndex:indexpath.row]?
I suggest placing a break point at line 2 and inspecting the content of dayOfWeekDictionary.
AND
In your comment, you set an instance of NSMutableArray into the variable dayOfWeekDictionary of type NSMutableDictionary, if you try to call [dayOfWeekDictionary setObject:[NSNumber numberWithBool:YES] forKey:#"isSelected"]; the application will crash with an unrecognized selector sent to instance.

Related

RemoveAllObjects equivalent fror NSArray

I know how I would achieve this using NSMutableArray, but whats the correct way of emptying a whole array of class NSArray. I need to do this because I need to reload a tableView. Im using ARC.
NSArray is an immutable type. You cannot alter it's contents after creation.
Either use an NSMutableArray or replace it with a new (empty) NSArray.
NSArray *yourArray = [ whatever objects you have ]
//to empty this array
yourArray = [NSArray array];
NSArray is an immutable (unchangeable) class so there is no way to remove elements from the array. Basically, you will have to throw the array away and replace it with a new NSArray. Alternatively, you could just use an NSMutableArray.
You cant empty a non mutable NSArray, the best approach is to get a mutable copy of your array:
NSMutableArray *arr=[yourArr mutableCopy];
[arr removeAllObjects];

Get the values from NSMutableDictionary inside NSMutableDictionary

I create two NSMutableDictionary: dictionary1 and dictionary2. In the first dictionary I store some array object having there keys. And in the second dictionary I store the object of first dictionary with the key like this:
int page = 1;
[dictionary2 setObject:dictionary1 forKey:[NSString stringWithFormat:#"%d",page]];
[dictionary1 removeAllObjects];
but at the time of retrieve of the object i do like this
dictionary1 = [dictionary2 valueForKey:[NSString stringWithFormat:#"%d",page]];
NSLog(#"dictionary1 %#", dictionary1);`
Then it gives null value. I don't know what mistake I do.
After you add dictionary1 to dictionary2, you are removing all of the objects.
This is the same dictionary that is in dictionary2 (it does not create a copy), therefore you are removing the objects from it as well.
You need to remove the line [dictionary1 removeAllObjects];.
Then, since you are done with dictionary1 at this point, you can either remove the reference to it or set to a nice new shiny dictionary which is ready to use:
// Remove the reference
dictionary1 = nil;
// Or, create a new, empty dictionary
dictionary1 = [[NSDictionary alloc] init];
Did you correctly alloc/init dictionary1 and dictionary2? Make sure the dictionaries themselves are not nil.
try this
dictionary1 = [dictionary2 objectForKey:[NSString stringWithFormat:#"%d",page]];

How do I archive an NSArray of NSDictionary (with NSCoding)?

Suppose I am holding data in an array like this
wordList = [[NSMutableArray alloc] init];
while ([rs next]) //Some database return loop
{
wordDict = [[NSMutableDictionary alloc] init];
[wordDict setObject:[NSNumber numberWithInt:[rs intForColumn:#"id"]] forKey:#"id"];
[wordDict setObject:[rs stringForColumn:#"word"] forKey:#"word"];
[wordList addObject: wordDict];
[wordDict release];
wordDict = nil;
}
But I want to store this result (i.e. wordList) in SQLite for later use - I guess using NSCoding. How would I do that?
(Feel free to point out any errors in how stuff is being alloc'ed if there are problems there).
If you don’t insist on serialization using NSCoding, there’s a writeToFile:atomically: method both on NSArray and NSDictionary. This will serialize your object into a property list (*.plist). The only catch is that all the objects in the “tree” to be serialized must be NSString, NSData, NSArray, or NSDictionary (see the documentation). I’m not sure how NSNumber fits in, but with a bit of luck it will be serialized and deserialized too. The inverse method that will turn the file back into a dictionary or an array is called initWithContentsOfFile:.
As for your code, I would just use the [NSMutableDictionary dictionary] convenience method that gets you an autoreleased dictionary. It’s shorter than the usual alloc & init and you save one line for the explicit release.

NSMutableDictionary setObject:forKey did't work when value is NSMutableArray

dict is NSMutableDictionary; array is NSMutableArray and is NOT nil;
The code:
[dict setObject:array forKey:#"key"];
There is no error or warning but the dict is null,nothing is set or added.
When I use the code below,it works:
[dict setObject:[NSArray arrayWithArray:array] forKey:#"Key"];
Can anyone tell me why ?
Update:
Both dict and array are local variables and have been initialized.The dict is nil.
NSLog(#"%#", array) has printed the value of array:
({"Title":"firstTitle","Date":"20110101"},{"Title":"secondTitle","Date":"20110102"})
UPDATE:
I have made a mistake.The array is not null at first,but I emptied it in follow operation.
Thanks for #Bavarious.
You're aware that you're using different capitalizations of "key", right? #"Key" is not the same thing as #"key".
I think you have not initialized array in 1st statement. check if its allocated memory or not?
The code seems to be correct. Most probably your array is nil.
When using arrayWithArray, the inserted object will be an array, even if its value itself is set to nil.

How to update NSMutableDictionary?

I have an NSMutableDictionary.
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
I have to update an element in that dictionary. How i can do that?
Please refer to the API here
First retrieve the objects using
[dict objectForKey:#"key"];
Later, you can set them back using:
- (void)setObject:(id)anObject forKey:(id)aKey
- (void)setValue:(id)value forKey:(NSString *)key
dictionary only allows you to have one objects for each key so if you use "set object for key" it will update the current one
NSMutableDictionary's method addEntriesFromDictionary.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/Reference/Reference.html
If both dictionaries contain the same key, the receiving dictionary’s previous value object for that key is sent a release message, and the new value object takes its place.