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

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.

Related

Set Value To Zero In Array

In my app I use the following code to set a value of an array to zero:
[[records objectAtIndex:prizenotify] setValue:nil forKey:#"marbles"];
NSError *error;
[_managedObjectContext save:&error]; //Save
But, It crashes my code. Am I coding this correctly? Marbles is an NSNumber.
Thanks!
[[records objectAtIndex:prizenotify] setValue:[NSNumber numberWithInteger:0] forKey:#"marbles"];
Or in modern Objective-C:
[records[prizenotify] setValue:#0 forKey:#"marbles"];
If you're looking to set a nil-esque value, you can use [NSNull null] to insert null/nil values into a collection class like NSArray.
Although I would choose Sean's solution ([NSNull null]) as the simplest solution, there is also the NSPointerArray class (which specifically answers your question). Here's the overview:
NSPointerArray is a mutable collection modeled after NSArray but it
can also hold NULL values, which can be inserted or extracted (and
which contribute to the object’s count). Moreover, unlike traditional
arrays, you can set the count of the array directly. In a garbage
collected environment, if you specify a zeroing weak memory
configuration, if an element is collected it is replaced by a NULL
value.
Make sure that [records objectAtIndex:prizenotify] object is a NSMutableDictionary.
To be sure, test :
[[((NSDictionary*)[records objectAtIndex:prizenotify]) mutableCopy] setValue:[NSNumber numberWithInteger:0] forKey:#"marbles"];
if this one works, the problem is that you just have a NSDictionary (not mutable).
If you have a NSMutableDictionary for sure :
If you want to set the value to zero, call :
[[records objectAtIndex:prizenotify] setValue:[NSNumber numberWithInteger:0] forKey:#"marbles"];
If you want to delete the 'marbles' key from the dictionary, call :
[[records objectAtIndex:prizenotify] removeObjectForKey:#"marbles"];

Mutating method send to immutable object

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.

NSMutableDictionary not Setting Keys

All,
I'm sure I'm overlooking something, but I've been staring at this code for too long trying to figure out what's going on.
-(IBAction)continue:(id)sender
{
//setters for the limits
NSLog(#"Log ageUnder18: %#", ageUnder18.text); //returns Y
NSMutableDictionary *cardLimits;
[cardLimits setObject:ageUnder18.text forKey:#"ageUnder18"];
NSLog(#"Just set %#", [cardLimits objectForKey:#"ageUnder18"]); //returns NULL
//more code here
}
Why is that returning NULL?
Thanks in advance,
James
You're not initializing your variable. In fact, you're rather lucky that you aren't crashing outright on the -setObject:forKey: line. Your cardLimits variable currently holds garbage memory, i.e. whatever was on the stack at the address that the variable occupies. You need to use
NSMutableDictionary *cardLimits = [NSMutableDictionary dictionary];
Note that the Static Analyzer should be able to catch this for you.
You are not allocating cardLimits at any time. You need:
NSMutableDictionary *cardLimits = [[NSMutableDictionary alloc] init];
You aren't initializing a NSMutableDictionary.

Adding string to an array

i wanted to know how to add strings into an array.
I used the following methods but it is showing null.
1) [arrData addObject:[NSString stringWithString:strlast]];
2) [arrData addObject:strlast];
Thanks in advance
You can't add anything to an NSArray once it's created. You need to use an NSMutableArray if you want to make changes to it.
Update: You may actually have two problems.
Using an NSArray instead of an NSMutableArray when mutability is needed.
Not initializing the array object (either kind). If arrData is nil, you can happily send as many messages as you want to nil. Nothing will happen.
If it is showing null (nil) you need to make sure you set arrData somewhere in your code before trying to addObject:.
arrData = [[NSMutableArray alloc] init];
Also strlast is a string so use your second example, the first example is pointless.
[arrData addObject:strlast];
Did you allocate an array and assign it to arrData?
Try:
NSMutableArray *arrData = [NSMutableArray array];
NSString *string = #"My string";
[arrData addObject:string];
NSLog(#"%#", [arrData objectAtIndex:0]); //logs "My string"
If you're using a non-mutable array, you can also use arrayByAddingObject:
arrData = [arrData arrayByAddingObject: strlast];
but a mutable array is probably a better idea.

iPhone - Registering an Array containing NSNulls with NSUserDefaults

I have the Array defined below.
NSMutableArray *tempMPArray = [NSMutableArray arrayWithCapacity:16];
for (int i=0; i < chapters; i++)
{
[tempMPArray addObject:[NSNull null]];
}
Every time I use it as a one of the objects of a dictionary below to register default values it crashes with EXC_BAD_ACCESS.
[[NSUserDefaults standardUserDefaults] registerDefaults:myDict];
If I replace the objects in the array with any other object NSNumber etc it works fine. What am I doing wrong with my array that NSUserDefaults rejects it ? The stack trace or NSZombie does not give any additional info.
While the solution may be a "work-around" I don't think it answers the underlying question. By providing a dictionary with [NSNull null] values he is providing NSUserDefaults with a valid dictionary. Why is it crashing? Is it something he is doing "wrong" or is it a bug in registerDefaults?
There may be circumstances where it is important to know whether say a user has entered a value (ie there is a valid string) or not entered a value (null) and the method of creating a "valid but empty string" can't determine if the empty string was because the user created a string with no characters or if he had never created a string at all. You may want different logic in these two cases.
I'm in the same boat, I have an NSUserDefault value I want to be [NSNull null] and everything I've read suggests the "right" way to put a null value in a dictionary is with [NSNull null] and my dictionary creates fine. But registerDefaults with this valid dictionary causes a crash. That suggests a bug in the implementation of registerDefaults doesn't it? What is wrong with the following and why does it crash?
NSArray *defaultValues = [NSArray arrayWithObjects:[NSNull null], nil];
NSArray *CurrentKeys = [NSArray arrayWithObjects: #"NullKey", nil];
NSDictionary *resourceDict = [NSDictionary dictionaryWithObjects:defaultValues forKeys:CurrentKeys];
[[NSUserDefaults standardUserDefaults] registerDefaults:resourceDict];
Ultimately, i think the answer is that the userDefaults get written out as a plist and plists don't support NSNull. if that's the case, the documentation for registerDefaults should say that only plist object types are allowed in the dictionary
Here's a better solution!
Define a static after #implementation
NSString *const Null = #"";
Then
NSMutableArray *tempDSArray = [NSMutableArray arrayWithCapacity:16];
for (i=0; i < chapters; i++)
{
[tempDSArray addObject:Null];
}
Everything else should work fine!