I have an array with multiple locations for different states.
{"location":"Lekki Phase 1","state":"abc","country":"Nigeria"},
{"location":"Lekki Phase 2","state":"xyz","country":"Nigeria"},
{"location":"Osapa London1","state":"def","country":"Nigeria"},
{"location":"Lekki Phase 2","state":"abc","country":"Nigeria"},
{"location":"Lekki Phase 3","state":"xyz","country":"Nigeria"},
{"location":"Osapa London 2","state":"def","country":"Nigeria"},..........
Now i can make an array for different states with no duplicate state , like
{"abc","xyz","def"}
But what i want is to display all locations state wise in a table.
How can i do this??
Using NSPredicate we can efficiently filter this . I have tried and tested working for me.
Here 'allDataArray' is array with dictionaries, You can replace your array here (the first one in your post)
NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 1" forKey:#"location"];
[dict1 setObject:#"abc" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 2" forKey:#"location"];
[dict1 setObject:#"xyz" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 2" forKey:#"location"];
[dict1 setObject:#"abc" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 3" forKey:#"location"];
[dict1 setObject:#"xyz" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
//NSLog(#"%#",allDataArray);
NSArray *state = [NSArray arrayWithObjects:#"abc",#"xyz", nil];
NSMutableArray *locationInState = [[NSMutableArray alloc] initWithCapacity:[state count]];
for(int i=0; i< [state count]; i++)
{
NSMutableArray *filteredarray = [[allDataArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(state == %#)", [state objectAtIndex:i]]] mutableCopy];
for(int j=0; j<[filteredarray count];j++)
{
NSDictionary *dict = [filteredarray objectAtIndex:j];
[filteredarray replaceObjectAtIndex:j withObject:[dict valueForKey:#"location"]];
}
[locationInState addObject:filteredarray];
}
NSLog(#"%#",locationInState);
Here locationInState array contains all location for filetred state. You can map them easily by index.
Result is
(
(
"Lekki Phase 1",
"Lekki Phase 2"
),
(
"Lekki Phase 2",
"Lekki Phase 3"
)
)
First It not array but it is Dictionary.
NSMutableDictionary * newDict = [NSMutableDictionary dictionaryWithCapacity:[OLdDict count]];
for(id item in [OLdDict allValues]){
NSArray * keys = [OLdDict allKeysForObject:item];
[newDict setObject:item forKey:[[OLdDict allKeysForObject:item] objectAtIndex:0]];
}
NSMutableDictionaries can act as uniquing collections (because they replace objects for keys if the same key is used twice). We can also take advantage of the fact that NSString is generally a constant address location, and funnel each one of those dictionaries into an array. To unique out each array of dictionaries, it would be far easier to wrap them in an object, but here goes:
-(void)uniquingSort {
//Setup collections for the uniquing process
NSMutableArray *datasource = //...
NSMutableIndexSet *hits = [NSMutableIndexSet indexSet];
NSMutableDictionary *uniquingDict = #{}.mutableCopy;
//Setup an index for the indexed set
int idx = 0;
//iterate through the array of dictionaries
for (NSArray *arrOfDicts in datasource) {
//get the dictionary we want to unique against
NSDictionary *innerDict = arrayOfDicts[1];
//do we have a dupe? If so, add its index to the index set
if (uniquingDict[innerDict[#"state"]] != nil)
[hits addIndex:idx];
uniquingDict[innerDict[#"state"]] = innerDict[#"state"];
idx++;
}
//cut out all the hits till we are only uniqued for the "state" key
[datasource removeObjectsAtIndexes:hits];
}
Related
I have the following result of NSDictionary of Array
Bath = {
Keynsham = (
"nsham companies"
);
};
Bath = {
"Midsomer Norton" = (
"Keynsham companies"
);
};
Bath = {
"Norton Radstock" = (
"Keynsham taxi companies"
);
};
Birmingham = {
"Acock's Green" = (
"Acock's Green taxi companies"
);
};
Birmingham = {
"Alcester Lane's End" = (
"Alcester Lane's End taxi companies"
);
};
How can i combine the values and keys so that I end up with only one category as shown below;
Bath = {
"Norton Radstock" = (
"Keynsham taxi companies"
);
"Midsomer Norton" = (
"Keynsham companies"
);
Keynsham = (
"nsham companies"
);
};
I am not sure if this is the best way to explain it
the code is as follows
//all Nssarrays allocated/ initialised
NSURL *url=[NSURL URLWithString:#"http://y.php"];
NSData *data= [NSData dataWithContentsOfURL:url];
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:Nil];
//instantiate arrays to hold data
NSMutableDictionary *dictArray=[[NSMutableDictionary alloc]init];
NSArray *cityName=[[NSArray alloc]init];
NSArray *townName=[[NSArray alloc]init];
NSArray *taxis=[[NSArray alloc]init];
NSArray *ids=[[NSArray alloc]init];
for (int i=0; i<json.count; i++)
{
//cityName=[[NSMutableArray alloc] initWithCapacity:json.count];
ids = [[json objectAtIndex:i] objectForKey:#"id"];
cityName = [[json objectAtIndex:i] objectForKey:#"cityName"];
townName=[[json objectAtIndex:i] objectForKey:#"townName"];
taxis=[[json objectAtIndex:i] objectForKey:#"taxis"];
NSMutableArray *taxisArray=[[NSMutableArray alloc] initWithObjects:taxis,nil];
NSMutableDictionary *towensdict=[[ NSMutableDictionary alloc] initWithObjectsAndKeys:taxisArray,townName, nil];
NSMutableDictionary *cities1=[[NSMutableDictionary alloc] initWithObjectsAndKeys:towensdict,cityName, nil];
NSLOG (#"%#", cities1) here, gives me the print out above
[dictArray addEntriesFromDictionary:cities1 ];
Then I tried Jdodgers solution as follows;
NSMutableDictionary *combinedDictionary = [[NSMutableDictionary alloc] init];
for (NSDictionary *currentDictionary in dictArray) {
NSArray *keys = [currentDictionary allKeys];
for (int n=0;n<[keys count];n++) {
NSMutableDictionary *dictionaryToAdd = [combinedDictionary valueForKey:[keys objectAtIndex:n]];
if (!dictionaryToAdd) dictionaryToAdd = [[NSMutableDictionary alloc] init];
[dictionaryToAdd setValuesForKeysWithDictionary:[currentDictionary valueForKey:[keys objectAtIndex:n]]];
[combinedDictionary setValue:dictionaryToAdd forKey:[keys objectAtIndex:n]];
NSLog(#"%#", currentDictionary);
}
}
//this gives error "unrecognized selector sent to instance", here is the print out
combinedDictionary NSMutableDictionary * 0x000000010012e580
currentDictionary NSDictionary *const 0x0000000100116460
dictArray NSMutableDictionary * 0x000000010012e220
[0] key/value pair
key id 0x0000000100116460
[0] id
value id 0x000000010012e440
[0] id
keys NSArray * 0x0000000000000000
You could create an NSMutableDictionary and loop through your array, adding the keys to the mutable dictionary using the allKeys.
For example, if your array was called dictArray, you could do:
NSMutableDictionary *combinedDictionary = [[NSMutableDictionary alloc] init];
for (NSDictionary *currentDictionary in dictArray) {
NSArray *keys = [currentDictionary allKeys];
for (int n=0;n<[keys count];n++) {
NSMutableDictionary *dictionaryToAdd = [combinedDictionary valueForKey:[keys objectAtIndex:n]];
if (!dictionaryToAdd) dictionaryToAdd = [[NSMutableDictionary alloc] init];
[dictionaryToAdd setValuesForKeysWithDictionary:[currentDictionary valueForKey:[keys objectAtIndex:n]]];
[combinedDictionary setValue:dictionaryToAdd forKey:[keys objectAtIndex:n]];
}
}
This code first creates a dictionary combinedDictionary that will be your final dictionary. It loops through all of the dictionaries in your array and for each one does the following:
First, it gets an array of all keys in the dictionary. For the dictionaries you provided this array will look like #[#"Bath"] for the first 3 and #[#"Birmingam"] for the other two.
The code then loops through these keys and gets the already existing dictionary from the combined dictionary from this key. If the dictionary doesn't exist, one is created.
Then, it adds all of the values from the dictionary from the array and sets the new dictionary to be the one in combinedDictionary.
I have input as two arrays shown below
NSArray *array1=[[NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:#"1",#"2",#"1", nil];
the output should resemble like this.
the same element should be cancelled only one time.
NSArray *array3=[[NSArray alloc]initWithObjects:#"1",#"2", nil];
THANKS IN ADVANCE.....
NSArray *array1 = #[#"1",#"2",#"3"];
NSArray *array2 = #[#"1",#"2",#"1"];
NSMutableSet *allElemets = [NSSet setWithArray:array1];
[allElemets addObjectsFromArray:array2];
This will return you all elements without duplicates.
In this case it will be
#"1",#"2",#"3"
Edit:
This will return the intersection of the arrays
NSMutableSet *set1 = [NSMutableSet setWithArray:array1];
NSSet *set2 = [NSSet setWithArray:array2];
[set1 intersectSet:set2];
Use NSCountedSet for the above situation
NSMutableArray *array1=[[NSMutableArray alloc]initWithObjects:#"r",#"a",#"r",#"r",#"r", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:#"b",#"c",#"r", nil];
NSMutableSet *setOne = [NSMutableSet setWithArray: array1];
NSSet *setTwo = [NSSet setWithArray: array2];
[setOne unionSet:setTwo];
NSArray *arrayOneResult = [setOne allObjects];
NSLog(#"%#",arrayOneResult);
NSMutableArray *resultArray = [[NSMutableArray alloc]init];
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:arrayOneResult];
for (id item in set)
{
NSCountedSet *set1 = [[NSCountedSet alloc] initWithArray:array1];
NSCountedSet *set2 = [[NSCountedSet alloc]initWithArray:array2];
int diff = abs([set1 countForObject:item] - [set2 countForObject:item]);
for (int i = 0 ;i < diff ;i++ ) {
[resultArray addObject:item];
}
}
NSLog(#"the array : %#",resultArray );
f you are fine with sets instead of arrays, you can use NSMutableSet instead of NSArray. NSMutableSet has nice methods like intersectSet: and minusSet:
if([[array1 objectAtIndex:i] isEqualToString:[array2 objectAtIndex:i]])
{
[array2 removeObjectAtIndex: i];
NSLog(#"same element removed.");
}
array3 = [firstArray arrayByAddingObjectsFromArray:secondArray];
or
NSMutableSet *set = [NSMutableSet setWithArray:array1];
[set addObjectsFromArray:array2];
array3 = [set allObjects];
Two arrays are compared and duplicate values are removed, you get your values.
Here tHe Code goes
EDIt: This WOuld remove the Duplicate Value add Unique value.
NSArray *array1=[[NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:#"1",#"2",#"1", nil];
//Here Create nEw Array with Arra1
NSMutableArray * newArray =[[NSMutableArray alloc] initWithArray:array1];
for(int index=0; index<[array2 count];index++)
{
id object =[array2 objectAtIndex:index];
if(![newArray containsObject:object])//this methods Returns YES/NO
{
[newArray addObject: object];
}
}
I have two arrays, both full of NSString objects like this:
NSMutableArray *titles = [[NSMutableArray alloc] initWithObjects:#"Title1", #"Title2", #"Title3", #"Title4", #"Title5", nil];
NSMutableArray *distances = [[NSMutableArray alloc] initWithObjects:#"139.45", #"23.78", #"347.82", #"10.29", #"8.29", nil];
How can I sort both arrays by the nearest distance first?
So the results would be like this:
titles = #"Title5", #"Title4", #"Title2", #"Title1", #"Title3"
distances = #"8.29", #"10.29", #"23.78", #"139.45", #"347.82"
I understand that NSSortDescriptor can be used in these circumstances but after looking through the documentation, I am still unsure about how.
I would sort the distances this way...
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSArray *sortedDistances = [listItem sortedArrayUsingComparator: ^(id a, id b) {
NSNumber *aNum = [f numberFromString:a];
NSNumber *bNum = [f numberFromString:b];
return [aNum compare:bNum];
}];
I can't think of a particularly quick way to get the associated titles sorted, but this should work ...
NSMutableArray *sortedTitles = [NSMutableArray array];
NSDictionary *distanceTitle = [NSDictionary dictionaryWithObjects:titles forKeys:distances];
for (NSString *distance in sortedDistances) {
NSString *associatedTitle = [distanceTitle valueForKey:distance];
[sortedTitles addObject:associatedTitle];
}
You can use an NSComparator block and use NSArray's sortedArrayUsingComparator method. On that block, you will receive two objects to compare, and base on the comparison result, you can use NSMutableArray exchangeObjectAtIndex:withObjectAtIndex: method to change the values of titles.
Here is a sample how I sort an array of dictionaries by distance value:
-(void)reorderByDistance {
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"distance" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
self.contentArray = [self.contentArray sortedArrayUsingDescriptors:sortDescriptors];
}
And my dictionary looks like this:
NSDictionary *dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:#"1", #"id", #"Business #1", #"name", #"This business does some pretty remarkable things", #"description", #"Alley Bar", #"category", #"1.2", #"distance", nil];
One approach would be to create a dictionary mapping titles to distances, sort the distances, and then iterate through the distances to recreate the titles:
NSMutableArray *titles = [[NSMutableArray alloc] initWithObjects:#"Title1", #"Title2", #"Title3", #"Title4", #"Title5", nil];
NSMutableArray *distances = [[NSMutableArray alloc] initWithObjects:#"139.45", #"23.78", #"347.82", #"10.29", #"8.29", nil];
//Create a map of current titles to distances
NSDictionary *titleDistanceMap = [NSDictionary dictionaryWithObjects:titles forKeys:distances];
//Need to sort the strings as numerical values
[distances sortUsingComparator:^(NSString *obj1, NSString *obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//Now re-populate the titles array
[titles removeAllObjects];
for (NSString *distance in distances){
[titles addObject:[titleDistanceMap objectForKey:distance]];
}
So I have three different arrays involved here...
I'm looping through golferThreeIcons (NSMutableArray), and I'm trying to take the highest 4 results (golferThreeIcons contains #'s as strings) and store them into the topFourIconsNum (NSMutableArray) and then I plan to store the id of that highest number in the array topFourIconsId (NSMutableArray).
One tricky thing is that golferThreeIcons start out at 99, but I want that to act like zero. So the number 99 should not get added to either of the arrays...
Example:
golferThreeIcons {2,1,5,3,9}
And after the loop went through I want it to show something like this...
topFourIconsId {0,2,3,4} --- 0 corresponds to 2 in golferThreeIcons --- 2 corresponds to 5 in golfer three icons
topFourIconsNum {2,5,3,9} ----(in any order as long as it corresponds to the top four icons id)
NSMutableArray *topFourIconsId = [NSMutableArray arrayWithObjects: #"0", #"0", #"0", #"0", #"0" ,nil];
NSMutableArray *topFourIconsNum = [NSMutableArray arrayWithObjects: #"0", #"0", #"0", #"0", #"0" ,nil];
int *ids = 0;
for (NSString *s in golferThreeIconCounter) {
if(s != #"0") {
int sint = [s intValue];
int *idn = 0;
for(NSString *n in topFourIconsNum) {
int nint= [n intValue];
if(sint == 99 && nint == 0) {
NSString *idstring = [NSString stringWithFormat:#"%d", ids];
NSString *sintstring = [NSString stringWithFormat:#"%d", sint];
[topFourIconsId replaceObjectAtIndex:idn withObject:idstring];
[topFourIconsNum replaceObjectAtIndex:idn withObject:sintstring];
NSLog(#"IN %#",sintstring);
break;
}
else {
if (sint > nint) {
NSString *idstring = [NSString stringWithFormat:#"%d", ids];
NSString *sintstring = [NSString stringWithFormat:#"%d", sint];
[topFourIconsId replaceObjectAtIndex:idn withObject:idstring];
[topFourIconsNum replaceObjectAtIndex:idn withObject:sintstring];
NSLog(#"IN %#",sintstring);
break;
}
}
idn++;
}
}
ids++;
}
Just a crazy idea
Put your golferThreeIcons in a NSDictionary with the array index as the key and the array value as the value and then sort the keys on their value:
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:#"2", #"1", #"5", #"3", #"9", nil] forKeys:[NSArray arrayWithObjects:#"0", #"1", #"2", #"3", #"4", nil]];
NSArray *sortedKeys = [dict keysSortedByValueUsingSelector:#selector(caseInsensitiveCompare:)];
NSLog([sortedKeys description]);
Here are two methods that return a dictionary of my custom four-propery objects. They make arrays of strings, floats and BOOLs to put in the Chemical objects, then build a dictionary from the arrays. I'm new enough to the whole memory management game that I'm not always sure when I own something and when to release it. I'm making all kinds of strings on the fly.
Here's the thing: The static analyzer sees no problem with the first method, - (id)generateChlorineDictionary but says there's a leak in the second one, - (id)generateCYADictionary. It says it starts at the NSMutableArray *cyaGranulesArray... and then goes to NSDictionary *cyaDictionary... and finally to the return cyaDictionary statement.
Here are the two methods; sorry they're so long!
EDIT: Changed name from generateChlorineDictionary to newChlorineDictionary
Removed a release that happened after the return
- (id)newChlorineDictionary {
// Sets up the array for the Bleach key
NSMutableArray *bleachArray = [[NSMutableArray alloc] init];
NSArray *bleachConcentrationArray = [[NSArray alloc] initWithObjects:#"6%", #"10%", #"12%", nil];
float bleachConstantArray[] = {0.0021400, 0.0012840, 0.0010700};
for (int i=0; i<3; i++) {
Chemical *bleachChemical = [[Chemical alloc] initWithChemical:#"Bleach"
andConcentration:[bleachConcentrationArray objectAtIndex:i]
andConstant:bleachConstantArray[i]
andIsLiquid:YES];
[bleachArray addObject:bleachChemical];
NSLog(#"bleachChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", bleachChemical.chemName, bleachChemical.chemConcentration, bleachChemical.chemConstant, bleachChemical.chemIsLiquid);
[bleachChemical release];
}
bleachConcentrationArray = nil;
// Sets up the array for the Trichlor key
NSMutableArray *trichlorArray = [[NSMutableArray alloc] init];
Chemical *trichlorChemical = [[Chemical alloc] initWithChemical:#"Trichlor"
andConcentration:#"90%"
andConstant:0.0001480
andIsLiquid:NO];
[trichlorArray addObject:trichlorChemical];
NSLog(#"trichlorChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", trichlorChemical.chemName, trichlorChemical.chemConcentration, trichlorChemical.chemConstant, trichlorChemical.chemIsLiquid);
[trichlorChemical release];
// Sets up the array for the Dichlor key
NSMutableArray *dichlorArray = [[NSMutableArray alloc] init];
NSArray *dichlorConcentrationArray = [[NSArray alloc] initWithObjects:#"56%", #"62%", nil];
float dichlorConstantArray[] = {0.0002400, 0.0002168};
for (int i=0; i<2; i++) {
Chemical *dichlorChemical = [[Chemical alloc] initWithChemical:#"Dichlor"
andConcentration:[dichlorConcentrationArray objectAtIndex:i]
andConstant:dichlorConstantArray[i]
andIsLiquid:NO];
[dichlorArray addObject:dichlorChemical];
NSLog(#"dichlorChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", dichlorChemical.chemName, dichlorChemical.chemConcentration, dichlorChemical.chemConstant, dichlorChemical.chemIsLiquid);
[dichlorChemical release];
}
dichlorConcentrationArray = nil;
// Sets up the array for the Cal Hypo key
NSMutableArray *calHypoArray = [[NSMutableArray alloc] init];
NSArray *calHypoConcentrationArray = [[NSArray alloc] initWithObjects:#"48%", #"53%", #"65", #"73", nil];
float calHypoConstantArray[] = {0.0002817, 0.0002551, 0.0002080, 0.0001852};
for (int i=0; i<2; i++) {
Chemical *calHypoChemical = [[Chemical alloc] initWithChemical:#"Cal Hypo"
andConcentration:[calHypoConcentrationArray objectAtIndex:i]
andConstant:calHypoConstantArray[i]
andIsLiquid:NO];
[calHypoArray addObject:calHypoChemical];
NSLog(#"calHypoChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", calHypoChemical.chemName, calHypoChemical.chemConcentration, calHypoChemical.chemConstant, calHypoChemical.chemIsLiquid);
[calHypoChemical release];
}
calHypoConcentrationArray = nil;
// Sets up the array for the Li Hypo key
NSMutableArray *liHypoArray = [[NSMutableArray alloc] init];
Chemical *liHypoChemical = [[Chemical alloc] initWithChemical:#"Li Hypo"
andConcentration:#"90%"
andConstant:0.0003800
andIsLiquid:NO];
[liHypoArray addObject:liHypoChemical];
NSLog(#"liHypoChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", liHypoChemical.chemName, liHypoChemical.chemConcentration, liHypoChemical.chemConstant, liHypoChemical.chemIsLiquid);
[liHypoChemical release];
// The array of keys for the chlorine chemicals
NSArray *chlorineKeys = [[NSArray alloc] initWithObjects:#"Bleach", #"Trichlor", #"Dichlor", #"Cal Hypo", #"Li Hypo", nil];
// The array of values for the chlorine chemicals
NSArray *chlorineValues = [[NSArray alloc] initWithObjects:bleachArray, trichlorArray, dichlorArray, calHypoArray, liHypoArray, nil];
[bleachArray release];
[trichlorArray release];
[dichlorArray release];
[calHypoArray release];
[liHypoArray release];
// The dictionary to hold the arrays of chlorine chemical objects
NSDictionary *chlorineDictionary = [[NSDictionary alloc] initWithObjects:chlorineValues forKeys:chlorineKeys];
[chlorineValues release];
[chlorineKeys release];
return chlorineDictionary;
}
EDIT: Changed name from generateCYADictionary to newCYADictionary
Removed a release that happened after the return
- (id)newCYADictionary {
// Sets up the array for the CYA Granules key
NSMutableArray *cyaGranulesArray = [[NSMutableArray alloc] init];
Chemical *cyaGranulesChemical = [[Chemical alloc] initWithChemical:#"CYA Granules"
andConcentration:#""
andConstant:0.0001330
andIsLiquid:NO];
[cyaGranulesArray addObject:cyaGranulesChemical];
NSLog(#"cyaGranulesChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", cyaGranulesChemical.chemName, cyaGranulesChemical.chemConcentration, cyaGranulesChemical.chemConstant, cyaGranulesChemical.chemIsLiquid);
[cyaGranulesChemical release];
// Sets up the array for the Liquid Stabilizer key
NSMutableArray *liquidStabilizerArray = [[NSMutableArray alloc] init];
Chemical *liquidStabilizerChemical = [[Chemical alloc] initWithChemical:#"Liquid Stabilizer"
andConcentration:#""
andConstant:0.0003460
andIsLiquid:YES];
[liquidStabilizerArray addObject:liquidStabilizerChemical];
NSLog(#"liquidStabilizerChemical: chemName = %#, chemConcentration = %#, chemConstant = %1.6f, chemIsLiquid = %d", liquidStabilizerChemical.chemName, liquidStabilizerChemical.chemConcentration, liquidStabilizerChemical.chemConstant, liquidStabilizerChemical.chemIsLiquid);
[liquidStabilizerChemical release];
// The array of keys for the CYA chemicals
NSArray *cyaKeys = [[NSArray alloc] initWithObjects:#"CYA Granules", #"Liquid Stabilizer", nil];
// The array of values for the CYA chemicals
NSArray *cyaValues = [[NSArray alloc] initWithObjects:cyaGranulesArray, liquidStabilizerArray, nil];
[cyaGranulesArray release];
[liquidStabilizerArray release];
// The dictionary to hold the arrays of CYA chemical objects
NSDictionary *cyaDictionary = [[NSDictionary alloc] initWithObjects:cyaValues forKeys:cyaKeys];
[cyaKeys release];
[cyaValues release];
return cyaDictionary;
}
Replace the
return cyaDictionary;
[cyaDictionary release];
With
return [cyaDictionary autorelease];
Or, you might replace the
NSDictionary *chlorineDictionary = [[NSDictionary alloc] initWithObjects:chlorineValues forKeys:chlorineKeys];
With
NSDictionary *chlorineDictionary = [NSDictionary dictionaryWithObjects:chlorineValues forKeys:chlorineKeys];
Instead of adding the autorelease.
In your original implementation the [cyaDictionary release]; is never executed (because it is after return).
You can use this dictionary outside this method and you shouldn't release it there.
You might want also return a retained object (without the autorelease) and release it outside the method. In this case you should start the method name with "new" or "alloc"...
EDIT (Important):
You should use only one of my suggestions.
Use the autorelease in the return line
Use the dictionaryWith...
Add the "new" or "alloc" prefix in the method name and release the returned object outside this method.
If you replace the alloc init with dictionaryWith... then you get an autoreleased object. And then, if you release it in the outer method then you have a serious problem (the object will try to release itself after the current runloop of the thread and it may crash the app because the object will already be released by you).
EDIT (due to one of the comments)
If you want to create a property that will return a dictionary:
// MyClass.h file
#interface MyClass : NSObject {
..
NSDictionary *_dict1;
..
}
#property (nonatomic, retain) NSDictionary *dict1;
..
#end
// MyClass.m file
#implementation MyClass
#synthesize dict1 = _dict1;
..
- (NSDictionary *)dict1 {
if (_dict1 == nil) {
NSDictionary *dict1Temp = [NSDictionary new];
// Your implementation goes here...
self.dict1 = dict1Temp;
[dict1Temp release];
}
}
..
- (void)dealloc {
[_dict1 release];
[suoer dealloc];
}
#end