NSMutableDictionary weird problem - objective-c

Say I have a class with two NSMutableDictionary.
#interface GameDataManager : CCNode {
NSMutableDictionary *worldInfoDictionary;
NSMutableDictionary *levelInfoDictionary;
}
#property (nonatomic, retain) NSMutableDictionary *worldInfoDictionary;
#property (nonatomic, retain) NSMutableDictionary *levelInfoDictionary;
And I load the data from the plist while the app start like this:
-(BOOL) readApplicationData:(NSString *)fileName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *myData = [[[NSData alloc] initWithContentsOfFile:appFile] autorelease];
if (myData == nil) {
return NO;
}
NSKeyedUnarchiver *un = [[NSKeyedUnarchiver alloc] initForReadingWithData:myData];
NSMutableDictionary *dic = [un decodeObjectForKey:#"GameData"];
self.worldInfoDictionary = [dic objectForKey:#"WorldInfoDictionary"];
self.levelInfoDictionary = [dic objectForKey:#"LevelInfoDictionary"];
for (int i = 1; i <= 10; i++) {
WorldInfoData * w = [worldInfoDictionary objectForKey:
[[[NSString alloc] initWithFormat:#"World%d", i] autorelease]];
NSLog(#"%d", w.worldNum);
[w release];
}
[un finishDecoding];
[un release];
return YES;
}
After the next two lines:
self.worldInfoDictionary = [dic objectForKey:#"WorldInfoDictionary"];
self.levelInfoDictionary = [dic objectForKey:#"LevelInfoDictionary"];
I can see the number of values/keys in two Dictionaries are right.
Then I tried to print out all the "worldNum" value for each object but the app
crahed:
2011-03-07 15:18:21.819 [1267:207] 1
2011-03-07 15:18:21.820 [1267:207] 2
2011-03-07 15:18:21.821 [1267:207] 3
2011-03-07 15:18:21.823 [1267:207] 4
2011-03-07 15:18:21.831 [1267:207] 5
2011-03-07 15:18:21.832 [1267:207] 6
2011-03-07 15:18:21.832 [1267:207] 7
2011-03-07 15:18:21.833 [1267:207] 8
2011-03-07 15:18:21.834 [1267:207] 9
2011-03-07 15:18:21.834 [1267:207] 10
Stack dump:
0. Running pass 'Sparse Conditional Constant Propagation' on function '#gleLLVMVecProjectionTransform2'
If I uncomment this line:
[un release];
The app works fine, no crash.
Can anybody explain this to me, thanks a lot^_^
Thanks for all the answers.
But if I delete the code lines I used to output some info:
for (int i = 1; i <= 10; i++) {
WorldInfoData * w = [worldInfoDictionary objectForKey:
[[[NSString alloc] initWithFormat:#"World%d", i] autorelease]];
NSLog(#"%d", w.worldNum);
[w release];
}
And uncomment the line "[un release];", the readApplicationData works fine,
but when I tried to read the data later like this:
NSMutableDictionary *dic = [GameDataManager sharedGameDataManager].worldInfoDictionary;
for (int i = 1; i <= 10; i++) {
NSString *key = [[NSString alloc] initWithFormat:#"World%d", i];
WorldInfoData *worldInfoData = [dic objectForKey:key];
if (worldInfoData.worldNum == 1) {
//......
}
[key release];
}
After this line : "WorldInfoData *worldInfoData = [dic objectForKey:key];", the type of worldInfoData
is not WorldInfoData * but CCArray, and since CCArray don't have property
worldNum, it crashed......

First, I would suggest running your application with Zombie detection enabled.
What you will find is a notification that you are overreleasing 'w'.
WorldInfoData * w = [worldInfoDictionary objectForKey:
[[[NSString alloc] initWithFormat:#"World%d", i] autorelease]];
NSLog(#"%d", w.worldNum);
[w release];
You add 'w' to the autorelease pool, but then call release on it explicitly. I would guess that getting rid of the [w release]; line will fix your problem or don't add 'w' to the autorelease pool.

Related

Twodimensional array into a UILabel

I have a twodimensional array where i i would like to print all second values of the objects into an UIlabel homePlayersFouls. the problem is i do not know how to this.
I have tried following things:
componentsJoinedByString:#"\n".
This will just print (
The other thing ive tried is this:
[[homePlayersArray objectAtIndex:i] objectAtIndex:1];
this just prints 0 since it looping and deleting the content inside label
i've checked wether there is something wrong the the array, but when i do this inside the loop:
nslog(#"%#",[[homePlayersArray objectAtIndex:i] objectAtIndex:1];);
It prints all 0 0 0 which is the 3 second values in my objects.
The question is then how can i print all my second values in all the objects in the array into an UIlabel?
here is the complete code:
for (int i=0;i<[homeNumbersArray count];i++){
NSArray *tempArray = [[NSArray alloc] initWithObjects:[homeNumbersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
[homePlayersArray addObject:tempArray];
NSObject* someObject = [[homePlayersArray objectAtIndex:i] objectAtIndex:1];
homePlayersFouls.text = [NSString stringWithFormat:#"%#", someObject];
}
You need:
homePlayersFouls.text = [homePlayersFouls.text stringByAppendingString:[NSString stringWithFormat:#"%#", someObject]];
NSMutableString *fouls = [NSMutableString string];
for (int i=0;i<[homeNumbersArray count];i++){
NSArray *tempArray = [[NSArray alloc] initWithObjects:[homeNumbersArray objectAtIndex:i],[NSNumber numberWithInt:0], nil];
[homePlayersArray addObject:tempArray];
NSObject* someObject = [[homePlayersArray objectAtIndex:i] objectAtIndex:1];
[fouls appendFormat:#"%#", someObject];
}
homePlayersFouls.text = fouls;

Reading from SQL database into NSArray

I have an iPad that reads data from an SQL database. The following code works fine and retrieves 2 fields from each record and reads them into an NSArray.
I now need to read 5 of the fields and I can't help but think that there is a better way of doing it rather than running 5 separate queries through php (the getinfo.php file with the choice parameter set to pick the different fields).
Any pointers to a better method for doing this?
NSString *strURLClass = [NSString stringWithFormat:#"%#%#", #"http://wwwaddress/getinfo.php?choice=1&schoolname=",obsSchoolName];
NSArray *observationsArrayClass = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
observationListFromSQL = [[NSMutableArray alloc]init];
NSEnumerator *enumForObsClass = [observationsArrayClass objectEnumerator];
NSString *strURLDate = [NSString stringWithFormat:#"%#%#", #"http://wwwaddress/getinfo.php?choice=5&schoolname=",obsSchoolName];
NSArray *observationsArrayDate = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLDate]];
observationListFromSQL = [[NSMutableArray alloc]init];
NSEnumerator *enumForObsDate = [observationsArrayDate objectEnumerator];
id className, dateOfObs;
while (className = [enumForObsClass nextObject])
{
dateOfObs = [enumForObsDate nextObject];
[observationListFromSQL addObject:[NSDictionary dictionaryWithObjectsAndKeys:className, #"obsClass", dateOfObs, #"obsDate",nil]];
}
Yes, you can do that with less code by "folding" the statements into a loop, and using a mutable dictionary:
// Add other items that you wish to retrieve to the two arrays below:
NSArray *keys = #[#"obsClass", #"obsDate"]; // Key in the dictionary
NSArray *choices = #[#1, #5]; // Choice in the URL string
NSMutableArray *res = [NSMutableArray array];
NSMutableArray *observationListFromSQL = [NSMutableArray array];
for (int i = 0 ; i != keys.count ; i++) {
NSNumber *choice = choices[i];
NSString *strURLClass = [NSString stringWithFormat:#"http://wwwaddress/getinfo.php?choice=%#&schoolname=%#", choice, obsSchoolName];
NSArray *observationsArray = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
NSEnumerator *objEnum = [observationsArrayClass objectEnumerator];
NSString *key = keys[i];
NSMutableDictionary *dict;
if (res.count < i) {
dict = res[i];
} else {
dict = [NSMutableDictionary dictionary];
[res addObject:dict];
}
id item;
while (item = [objEnum nextObject]) {
[res setObject:item forKey:key];
}
}

How to parse 5 Arrays in one object using JSON

I'm stuck at this problem, The output of the JSOn is
"forecast":[
{"day":"Today","condition":"MostlyClear","high_temperature":"94","low_temperature":"70"},
{"day":"Tomorrow","condition":"Sunny","high_temperature":"95","low_temperature":"69"},
{"day":"Saturday","condition":"Sunny","high_temperature":"94","low_temperature":"71"},
{"day":"Sunday","condition":"Sunny","high_temperature":"93","low_temperature":"70"},
{"day":"Monday","condition":"Sunny","high_temperature":"94","low_temperature":"70"}
]
I need condition key to show the values in the tableview cell. And my code is
temp=[[NSString alloc] initWithData:[dataLoader httpData] encoding:NSUTF8StringEncoding];
NSLog(#"Patient Details %#",temp);
array = [[temp JSONValue] objectForKey:#"forecast"];
NSDictionary* dic = [array objectAtIndex:[indexPath row]];
NSString *strDay = [dic objectForKey:#"day"];
NSString *stringCondition = [dic objectForKey:#"condition"];
NSLog(#"condition is %#", stringCondition);
NSString *stringTemp = [dic objectForKey:#"high_temperature"];
NSString *stringLow = [dic objectForKey:#"low_temperature"];
But it is showing only one condition value, i want all the five conditions at a time. I also tried to use NSArray instead of NSString for condtion with no luck.
array = [[temp JSONValue] objectForKey:#"forecast"];
Make a for loop in this place :
for(NSUInteger index = 0; index<[array count]; index++)
{
NSDictionary* dic = [array objectAtIndex:index];
NSString *strDay = [dic objectForKey:#"day"];
NSString *stringCondition = [dic objectForKey:#"condition"];
NSLog(#"condition is %#", stringCondition);
NSString *stringTemp = [dic objectForKey:#"high_temperature"];
NSString *stringLow = [dic objectForKey:#"low_temperature"];
}
Hope this will help...

JSON text and variable count

I am reading like this...
NSString *fileContent = [[NSString alloc] initWithContentsOfFile:path];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *data = (NSDictionary *) [parser objectWithString:fileContent error:nil];
// getting the data from inside of "menu"
NSString *message = (NSString *) [data objectForKey:#"message"];
NSString *name = (NSString *) [data objectForKey:#"name"];
NSArray *messagearray = [data objectForKey:#"message"];
NSArray *namearray = [data objectForKey:#"name"];
NSDictionary* Dictionary = [NSDictionary dictionaryWithObjects:message forKeys:name];
for (NSString* Key in [Dictionary allKeys]){
NSLog(#"%# %#",Key,[Dictionary objectForKey:Key]);
}
...this JSON file...
{"message":["Untitled1a","Untitled2a","Untitled3a"],"name": ["Untitled1b","Untitled2b","Untitled3b"]}
...this is the result...
Untitled3b Untitled3a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled1b Untitled1a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled2b Untitled2a
...but for each pair (Untitled 1b 2b) I would like to alloc two UITextFields, witch display the correspondent text...
I tried using this method:
for (NSString *string in messagearray){
}do{
NSLog(#"happt = %i", b);
b++;
}
while(b == b);
//While loop
while (b == b ) {
NSLog(#"x = %i", b);
b++;
}
}
I would like to count the objects in the array in order to repeat an alloc code for UITextField that number of times, and display the text accordingly, but I am not able. Please help!!
Why can't you use -count?
b = [messagearray count]
To directly answer your question:
b = 0;
for (id item in messagearray)
b++;

How to prevent all rows of an NSTableView being selected at startup

I am new to Objective-C. I am using NSArrayController to fill NSTableView. Initially, I am getting all rows selected in the table view. I am unable to find the reason behind it.
for(int i=0;i<nCount;i++)
{
NSString *fileName_File = [[[filenames objectAtIndex:i] lastPathComponent] stringByDeletingPathExtension];
NSString *pathExtension = [[filenames objectAtIndex:i] pathExtension];
NSString *yourPath = [filenames objectAtIndex:i];
NSFileManager *fmgr = [[NSFileManager alloc] init];
NSDictionary *attrs = [fmgr attributesOfItemAtPath: yourPath error: nil];
[attrs retain];
UInt32 result = [attrs fileSize];
/*NSString * zStr1 = [[NSString alloc]initWithFormat:#"%d",i+1];
NSString * zStr2 = [[NSString alloc]initWithFormat:#"%#",fileName_File];
NSString * zStr3 = [[NSString alloc]initWithFormat:#"%#",pathExtension];
NSString * zStr4 = [[NSString alloc]initWithFormat:#"%d",result];
NSString * zStr5 = [[NSString alloc]initWithFormat:#"%#",[filenames objectAtIndex:i]];*/
CMyMediaData * MyMediaObj = [[CMyMediaData alloc]initWithString1:[[NSString alloc]initWithFormat:#"%#",#""]
andString2:[[NSString alloc]initWithFormat:#"%#",fileName_File]
andString3:[[[NSString alloc]initWithFormat:#"%#",pathExtension]uppercaseString]
andString4:[[NSString alloc]initWithFormat:#"%d",result]
andString5:[[NSString alloc]initWithFormat:#"%#",[filenames objectAtIndex:i]]
];
[attrs release];
[mMedia.mcMediaController.mcTableViewMyMedia addObject:MyMediaObj];
//[mMedia.nsMutaryOfDataObject addObject:MyMediaObj];
} this is the code to add data to nsarraycontroller object.mcMediaController is object of NSArrayController
NSArrayController has a property selectsInsertedObjects. If that is YES, inserted objects are marked selected, including the ones added by addObject:.
You can set that property to NO, or you can use the following to unset the selection after adding the items:
mMedia.mcMediaController.mcTableViewMyMedia.selectedObjects = #[];