Getting strange error in NSDictionary - iphone

I am getting strange exception when calling the NSDictionary in the following example:
NSInteger userId = 1;
NSDictionary *postData = [NSDictionary dictionaryWithObjectsAndKeys:
#"3", #"a",
#"0", #"b",
userId, #"c",
nil];
Can someone see what's the problem above?

NSDictionary, as most collections, just accepts real Obj-C objects (id type), but you are passing a NSInteger which is a normal C typedef.
Try with NSNumber userId = [NSNumber numberWithInt:1];

Related

EXC_BAD_ACCESS on NSMutableDictionary

I am beginning with iOS development, I have this code :
First of all I declare the listOfItems NSMutableArray:
#interface SAMasterViewController () {
NSMutableArray *listOfItems;
}
#end
And now, here is the part the code that gives me an "EXC_BAD_ACCESS (code=1, address=0x5fc260000)" error.
The error is given in the last line of the "individual_data" object.
listOfItems = [[NSMutableArray alloc] init];
for(NSDictionary *tweetDict in statuses) {
NSString *text = [tweetDict objectForKey:#"text"];
NSString *screenName = [[tweetDict objectForKey:#"user"] objectForKey:#"screen_name"];
NSString *img_url = [[tweetDict objectForKey:#"user"] objectForKey:#"profile_image_url"];
NSInteger unique_id = [[tweetDict objectForKey:#"id"] intValue];
NSInteger user_id = [[[tweetDict objectForKey:#"user"] objectForKey:#"id"] intValue ];
NSMutableDictionary *individual_data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
text, #"text_tweet",
screenName,#"user_name",
img_url, #"img_url",
unique_id, #"unique_id",
user_id, #"user_id", nil];
[listOfItems addObject:individual_data];
}
Thanks in advance.
You can not put NSIntegers or any other non Objective-C class inside of an array or dictionary. You need to wrap them in an NSNumber.
NSMutableDictionary *individual_data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
text, #"text_tweet",
screenName,#"user_name",
img_url, #"img_url",
[NSNumber numberWithInteger:unique_id], #"unique_id",
[NSNumber numberWithInteger:user_id], #"user_id", nil];
//Or if you want to use literals
NSMutableDictionary *individual_data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
text, #"text_tweet",
screenName,#"user_name",
img_url, #"img_url",
#(unique_id), #"unique_id",
#(user_id), #"user_id", nil];

Insert NSArray into an NSDictionary

If I have a NSArray, can I put this into a NSDictionary?
If so, how can I do this?
An NSDictionary can use any objects as values, and any objects that conforms to NSCopyingas keys. So in your case:
NSArray * myArray = [NSArray arrayWithObjects:#"a", #"b", #"c"];
NSDictionary * dict = [NSDictionary dictionaryWithObject:myArray forKey:#"threeLetters"];
NSMutableDictionary * mutableDict = [NSMutableDictionary dictionaryWithCapacity:10];
[mutableDict setObject:myArray forKey:#"threeLetters"];
If you start with myArray:
NSArray *myArray = [NSArray arrayWithObjects:...];
If you want a mutable dictionary:
NSMutableDictionary *myMutableDictionary = [NSMutableDictionary dictionary];
[myMutableDictionary setObject:myArray forKey:#"myArray"];
If you just want a dictionary:
NSDictionary *myDictionary = [NSDictionary dictionaryWithObject:myArray forKey:#"myArray"];
Maybe you should read this:
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Collections/Collections.html#//apple_ref/doc/uid/10000034i

Init array with bool values

my attempt to init an array with a number of bool values using:
[myArray initWithObjects:[NSNumber numberWithBool:YES],
[NSNumber numberWithBool:YES],
[NSNumber numberWithBool:YES],
nil];
seems to fail since the debugger shows an empty array after this statement is carried out ... Any clues?
Make sure you are alloc-ing the object, as well, i.e.:
NSArray *myArray = [[NSArray alloc] initWithObjects:...];
...
[myArray release];
Or:
NSArray *myArray = [[[NSArray alloc] initWithObjects:...] autorelease];
Or:
NSArray *myArray = [NSArray arrayWithObjects:...];

How can we store into an NSDictionary? What is the difference between NSDictionary and NSMutableDictionary?

I am developing an application in which I want to use an NSDictionary. Can anyone please send me a sample code explaining the procedure how to use an NSDictionary to store Data with a perfect example?
The NSDictionary and NSMutableDictionary docs are probably your best bet. They even have some great examples on how to do various things, like...
...create an NSDictionary
NSArray *keys = [NSArray arrayWithObjects:#"key1", #"key2", nil];
NSArray *objects = [NSArray arrayWithObjects:#"value1", #"value2", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
forKeys:keys];
...iterate over it
for (id key in dictionary) {
NSLog(#"key: %#, value: %#", key, [dictionary objectForKey:key]);
}
...make it mutable
NSMutableDictionary *mutableDict = [dictionary mutableCopy];
Note: historic version before 2010: [[dictionary mutableCopy] autorelease]
...and alter it
[mutableDict setObject:#"value3" forKey:#"key3"];
...then store it to a file
[mutableDict writeToFile:#"path/to/file" atomically:YES];
...and read it back again
NSMutableDictionary *anotherDict = [NSMutableDictionary dictionaryWithContentsOfFile:#"path/to/file"];
...read a value
NSString *x = [anotherDict objectForKey:#"key1"];
...check if a key exists
if ( [anotherDict objectForKey:#"key999"] == nil ) NSLog(#"that key is not there");
...use scary futuristic syntax
From 2014 you can actually just type dict[#"key"] rather than [dict objectForKey:#"key"]
NSDictionary *dict = [NSDictionary dictionaryWithObject: #"String" forKey: #"Test"];
NSMutableDictionary *anotherDict = [NSMutableDictionary dictionary];
[anotherDict setObject: dict forKey: "sub-dictionary-key"];
[anotherDict setObject: #"Another String" forKey: #"another test"];
NSLog(#"Dictionary: %#, Mutable Dictionary: %#", dict, anotherDict);
// now we can save these to a file
NSString *savePath = [#"~/Documents/Saved.data" stringByExpandingTildeInPath];
[anotherDict writeToFile: savePath atomically: YES];
//and restore them
NSMutableDictionary *restored = [NSDictionary dictionaryWithContentsOfFile: savePath];
The key difference: NSMutableDictionary can be modified in place, NSDictionary cannot. This is true for all the other NSMutable* classes in Cocoa. NSMutableDictionary is a subclass of NSDictionary, so everything you can do with NSDictionary you can do with both. However, NSMutableDictionary also adds complementary methods to modify things in place, such as the method setObject:forKey:.
You can convert between the two like this:
NSMutableDictionary *mutable = [[dict mutableCopy] autorelease];
NSDictionary *dict = [[mutable copy] autorelease];
Presumably you want to store data by writing it to a file. NSDictionary has a method to do this (which also works with NSMutableDictionary):
BOOL success = [dict writeToFile:#"/file/path" atomically:YES];
To read a dictionary from a file, there's a corresponding method:
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:#"/file/path"];
If you want to read the file as an NSMutableDictionary, simply use:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:#"/file/path"];

Creating an NSDictionary

In the following code, the first log statement shows a decimal as expected, but the second logs NULL. What am I doing wrong?
NSDictionary *entry = [[NSDictionary alloc] initWithObjectsAndKeys:
#"x", [NSNumber numberWithDouble:acceleration.x],
#"y", [NSNumber numberWithDouble:acceleration.y],
#"z", [NSNumber numberWithDouble:acceleration.z],
#"date", [NSDate date],
nil];
NSLog([NSString stringWithFormat:#"%#", [NSNumber numberWithDouble:acceleration.x]]);
NSLog([NSString stringWithFormat:#"%#", [entry objectForKey:#"x"]]);
You are exchanging the order in which you insert objects and key: you need to insert first the object, then the key as shown in the following example.
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:#"value1", #"key1", #"value2", #"key2", nil];
new Objective-c supports this new syntax for static initialisation.
#{key:value}
For example:
NSDictionary* dict = #{#"x":#(acceleration.x), #"y":#(acceleration.y), #"z":#(acceleration.z), #"date":[NSDate date]};
NSDictionary Syntax:
NSDictionary *dictionaryName = [NSDictionary dictionaryWithObjectsAndKeys:#"value1",#"key1",#value2",#"key2", nil];
Example:
NSDictionary *importantCapitals = [NSDictionary dictionaryWithObjectsAndKeys:
#"NewDelhi",#"India",#"Tokyo",#"Japan",#"London",#"UnitedKingdom", nil];
NSLog(#"%#", importantCapitals);
Output looking like,
{India = NewDelhi; Japan = Tokyo; UnitedKingdom = London; }