I have a NSMutableArray of NSMutableDictionary but when i access the values of the array they are always nil. Here is the code i'm using
NSMutableDictionary *tmpDictionary = [[NSMutableDictionary alloc] init];
self.arrayOfData = [[NSMutableArray alloc] init];
[tmpDictionary setObject:#aaa forKey:Key1];
[tmpDictionary setObject:#1 forKey:Key2];
[tmpDictionary setObject:#1 forKey:Key3];
[tmpDictionary setObject:#10.0f forKey:Key4];
[tmpDictionary setObject:#10.0f forKey:Key5];
[self.arrayOfData addObject:tmpDictionary];
[tmpDictionary removeAllObjects];
[tmpDictionary setObject:#bbb forKey:Key1];
[tmpDictionary setObject:#1 forKey:Key2];
[tmpDictionary setObject:#2 forKey:Key3];
[tmpDictionary setObject:#50.0f forKey:Key4];
[tmpDictionary setObject:#50.0f forKey:Key5];
[self.arrayOfData addObject:tmpDictionary];
[tmpDictionary removeAllObjects];
And i access the Array in this way
for (int i = 0; i < self.arrayOfData.count; ++i) {
NSLog(#"%#", [self.arrayOfData[i] objectForKey:Key3]);
}
But the log always returns nil.
What's my mistake?
Thanks in advance
There is only one dictionary, and it is mutable. When [tmpDictionary removeAllObjects]; gets called, all the objects are removed, so it is empty afterwards. To fix this, create multiple mutable dictionaries, and don't empty them.
The issue is due to reusing tmpArray over and over and removing all of the objects from the array. That won't work. Do it this way:
self.arrayOfData = [[NSMutableArray alloc] init];
NSMutableDictionary *tmpDictionary = [[NSMutableDictionary alloc] init];
[tmpDictionary setObject:#aaa forKey:Key1];
[tmpDictionary setObject:#1 forKey:Key2];
[tmpDictionary setObject:#1 forKey:Key3];
[tmpDictionary setObject:#10.0f forKey:Key4];
[tmpDictionary setObject:#10.0f forKey:Key5];
[self.arrayOfData addObject:tmpDictionary];
tmpDictionary = [[NSMutableDictionary alloc] init];
[tmpDictionary setObject:#bbb forKey:Key1];
[tmpDictionary setObject:#1 forKey:Key2];
[tmpDictionary setObject:#2 forKey:Key3];
[tmpDictionary setObject:#50.0f forKey:Key4];
[tmpDictionary setObject:#50.0f forKey:Key5];
[self.arrayOfData addObject:tmpDictionary];
Even better would be use modern syntax:
self.arrayOfData = [[NSMutableArray alloc] init];
NSDictionary *tmpDictionary = #{
Key1 : #aaa",
Key2 : #1,
Key3 : #1,
Key4 : #10.0f,
Key5 : #10.0f
};
[self.arrayOfData addObject:tmpDictionary];
tmpDictionary = #{
Key1 : #bbb",
Key2 : #1,
Key3 : #2,
Key4 : #50.0f,
Key5 : #50.0f
};
[self.arrayOfData addObject:tmpDictionary];
#rmaddy is right.
Just as small addition.
You probably think that -addObject: method copies dictionary object to array (creates a copy of object). It doesn't
.
It just stores reference to the tmpDictionary in dictionary. You basically save pointer to the memory part which has your dictionary.
What you do in your code:
Create a NSMutableDictionary instance
Fill this instance with some data
Add pointer to this instance to the array
Remove oll objects from dictionary (the one in the array will be empty at this point)
Create another instance of NSMutableDictionary
Repeat 2-4
To illustrate that - put this NSLog after adding dictionary first time to the array. This NSLog will print memory addresses of the tmpDictionary and array item with index 0. You'll see that it is exactly same object
NSLog(#"tmpDictionary: %p, Array Item 0: %p", tmpDictionary, self.arrayOfData[0]);
Hope I explained it well...
Related
I have two NSMutableArrays, both getting the same data. My problem is that when I assign the same data to both the mutable arrays from different dictionaries and perform operations on one NSMutableArray, it is affecting both arrays.
When I perform operations like replaceObjectAtIndex:WithObject:, the first time, the array is not affected but when the second replace is called both arrays have the replaced value. I think it is a reference issue.
Does anyone have a solution to this?
Name of the NSMutableArrays is helper.urlsRecording and helper.holdingArr.
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
[dict setValue:outputFileURL forKey:#"URL"];
[dict setValue:#"1" forKey:#"index"];
[dict2 setValue:outputFileURL forKey:#"URL"];
[dict2 setValue:#"1" forKey:#"index"];
[helper.urlsRecording addObject:dict];
[helper.holdingArr addObject:dict2];
[helper.urlsRecording replaceObjectAtIndex:button.tag withObject:urlAr];//When this called second time, both the arrays is effected(helper.urlsRecording as well as helper.holdingArr).
How can I prevent the copying of the reference to another array?
Button Click:
if([button isSelected] == NO){
NSLog(#"Url Recording : %#",helper.urlsRecording);
[[helper.urlsRecording objectAtIndex:button.tag] removeObjectForKey:#"URL"];
button.selected = YES;
NSLog(#"Url Recording : %#",helper.urlsRecording);
}
else{
[helper.urlsRecording replaceObjectAtIndex:button.tag withObject:[helper.holdingArr objectAtIndex:button.tag]];
button.selected = NO;
NSLog(#"Url Recording : %#",helper.urlsRecording);
}
Note: NSMutableArray is defined globally in a class to access.
This is because your instance values are same for both dictionary.
So First create one mutableDictionary like below
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:outputFileURL forKey:#"URL"];
[dict setValue:#"1" forKey:#"index"];
And create second dictionary through mutableCopy, so instance will be different for both.
NSMutableDictionary *dict2 = [dict mutableCopy];
After that you can add them in to NSMutableArray and update accordingly.
Take a copy/mutableCopy dictionary & then add object to the MutableArray
[helper.urlsRecording addObject:[dict copy]];
[helper.holdingArr addObject:[dict2 copy]];
I am very new to Objective-C and iOS programming so be gentle :)
I am trying to add an nsmutabledictionary to and nsmutablearray. I am succeeding but not with the results I was hoping for. Here is my code :
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *messages = [[NSMutableDictionary alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
[dictionary setValue:#"lat1" forKey:#"lat"];
[dictionary setValue:#"long1" forKey:#"long"];
[dictionary setValue:#"alt1" forKey:#"alt"];
[messages setObject:dictionary forKey:#"messages"];
[array addObject:messages];
[dictionary setValue:#"lat2" forKey:#"lat"];
[dictionary setValue:#"long2" forKey:#"long"];
[dictionary setValue:#"alt2" forKey:#"alt"];
[messages setObject:dictionary forKey:#"messages"];
[array addObject:messages];
NSLog(#"%#",array);
NSLog(#"%lu",(unsigned long)[array count]);
Here is the NSLog output:
2014-06-05 10:29:27.377 dicttest[4863:60b] (
{
messages = {
alt = alt2;
lat = lat2;
long = long2;
};
},
{
messages = {
alt = alt2;
lat = lat2;
long = long2;
};
}
)
2014-06-05 10:29:27.386 dicttest[4863:60b] 2
Here is what I was hoping to achieve:
2014-06-05 10:29:27.377 dicttest[4863:60b] (
{
messages = {
alt = alt1;
lat = lat1;
long = long1;
};
},
{
messages = {
alt = alt2;
lat = lat2;
long = long2;
};
}
)
2014-06-05 10:29:27.386 dicttest[4863:60b] 2
If I the dictionary straight to the array (instead of add the dictionary to messages and then adding that to the array) then I get the output I am looking for. Can somebody explain to me exactly what I am doing wrong?
It looks to me like you want:
An array
At index 0:
A dictionary with a single key "messages"
A dictionary with keys "alt", "lat", and "long"
At index 1:
A dictionary with a single key "messages"
A dictionary with keys "alt", "lat", and "long"
The data in the second array entry should use the same keys, but different data. As the others have pointed out, your mistake is using a single dictionary "dictionary"
When you add an object to a collection like a dictionary or array, the collection holds a pointer to the object, not a copy of the object. If you add the same object to a collection more than once, you have 2 pointers to the same object, not 2 unique objects.
When you add your "dictionary" object, to your structure, change it, and add it again, you are not getting the result you expect because both entries in your structure point to a single dictionary. When you change the values, it changes in both places.
The same goes for your "messages" dictionary. You need 2 of those as well.
Fix your code by adding new dictionaries, dictionary2 and messages2:
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dictionary2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *messages = [[NSMutableDictionary alloc] init];
NSMutableDictionary *messages2 = [[NSMutableDictionary alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init];
[dictionary setValue:#"lat1" forKey:#"lat"];
[dictionary setValue:#"long1" forKey:#"long"];
[dictionary setValue:#"alt1" forKey:#"alt"];
[messages setObject:dictionary forKey:#"messages"];
[array addObject:messages];
[dictionary2 setValue:#"lat2" forKey:#"lat"];
[dictionary2 setValue:#"long2" forKey:#"long"];
[dictionary2 setValue:#"alt2" forKey:#"alt"];
[messages2 setObject: dictionary2 forKey:#"messages"];
[array addObject: messages2];
NSLog(#"%#",array);
NSLog(#"%lu",(unsigned long)[array count]);
You might also look at using object literal syntax, e.g.:
dictionary[#"lat"] = #"lat1";
dictionary[#"long"] = #"long1";
dictionary[#"alt"] = #"alt1";
messages[#"messages"] = dictionary;
If you didn't need the whole thing to be mutable, you could even do everything with one line:
NSMutableArray *array = [
#[
#{#"messages": #{#"lat": #"lat1", #"long": #"long1", #"alt": #"alt1"}},
#{#"messages": #{#"lat": #"lat2", #"long": #"long2", #"alt": #"alt2"}}
];
Or to make it mutable:
NSMutableArray *array = [
#[
[#{#"messages":
[#{#"lat": #"lat1", #"long": #"long1", #"alt": #"alt1"} mutableCopy]} mutableCopy],
[#{#"messages":
[#{#"lat": #"lat2", #"long": #"long2", #"alt": #"alt2"} mutableCopy]} mutableCopy]
] mutableCopy];
EDIT: to add contents dynamically, you could use a method like this: (assuming that array is an instance variable)
- (void) addMessageWithLat: (NSString *) latString
long: (NSString *) longString
alt: (NSString *) altString;
{
NSMutableDictionary *messages = [[NSMutableDictionary alloc] init];
NSDictonary *contents =
[#{#"lat": latString,
#"long": longString,
#"alt": altString}
mutableCopy];
messages[#"messages"] = contents;
[array addObject: messages];
}
The problem is that you are making adding the new values in the same object reference. So the new Value will replace the older one. Just add this line before [dictionary setValue:#"lat2" forKey:#"lat"];
dictionary = [NSMutableDictionary alloc]init];
and this line before the second instance of [messages setObject:dictionary forKey:#"messages"];
messages = [[NSMutableDictionary alloc] init];
I am working with an application in which i am getting photoID ,which is a string.
I am storing that photoID in array,and again add that array in another array.
Below iS the code::
NSString *photoID;
arr=[[NSMutableArray alloc]initWithCapacity:10];
array=[[NSMutableArray alloc] init];
[array addObject:photoID];
[arr arrayByAddingObjectsFromArray:array];
//number=(int)arr[1];
NSLog(#"arr : %#",arr);
NSLog(#"arr[0] : %#",arr[0]);
NSLog(#"arr[1] : %#",arr[1]);
NSLog(#"Number1 : %#",number1);
NSLog(#"Number : %d",number);
when i tried to access the value of arr[1],my application crashes.
i don't know what am i doing wrong.am i doing wrong to add strings in array,and truing to access unsaved data?
Please help me out.
Thanks in advance
It is because this line: [arr arrayByAddingObjectsFromArray:array]; does nothing to the arr, it only
Returns a new array that is a copy of the receiving array with the
objects contained in another array added to the end.
You should replace it with [arr addObjectsFromArray:array];. And also, you only have 1 element in arr which is at index 0, so the arr[1] should crash but arr[0] should work.
First array should be NSArray if you want to arrayByAddingObjectsFromArray or addObjectsFromArray
NSArray *array1=[[NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSMutableArray *array2=[[NSMutableArray alloc]init];
[array2 addObjectsFromArray:array1];
NSLog(#"%d",array2.count);
You can also use like this:
NSMutableArray *innerArray = [[NSMutableArray alloc] initWithObjects:#"1",#"2",#"3", nil];
NSMutableArray *outerArray = [NSMutableArray array];
for(int i=0;i<=innerArray.count;i++)
{
[outerArray addObject:innerArray];
}
I'm scanning an NSMutableArray of dictionary's and request to a WebService a info from each data.
The problem is after get the data, i need to update 2 keys of the same array of dictionary's and when i added an object, the array continues empty.
What is wrong?!
PS: using ARC
NSMutableArray* arrayOfDicts = [NSMutableArray arrayWithObjects:
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"2013",#"year",
#"a1beb511-7fe1-434b-ab87-a0d02fb47713",#"yearTB",
#"",#"receita_arrecadada",
#"",#"receita_prevista_atualizada",
nil],
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"2012",#"year",
#"5d20f841-d790-4671-ae26-505c9a8c7f76",#"yearTB",
#"",#"receita_arrecadada",
#"",#"receita_prevista_atualizada",
nil],
nil];
__block NSMutableArray* arrayTemp = [[NSMutableArray alloc] init];;
__block NSMutableDictionary* dicTemp;
for(dicTemp in arrayOfDicts){
NSString* year = [dicTemp objectForKey:#"year"];
NSString* yearTB = [dicTemp objectForKey:#"yearTB"];
NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
[RequestFacade getReceiptsTotalInYear:[NSString stringWithFormat:#"%#", yearTB] andCompletion:^(Receipt *receipt) {
//NSLog(#"%#",receipt.receita_arrecadada); // Print the correct actual value
[newDict addEntriesFromDictionary:dicTemp];
[newDict setObject:year forKey:#"year"];
[newDict setObject:yearTB forKey:#"yearTB"];
[newDict setObject:receipt.receita_arrecadada forKey:#"receita_arrecadada"];
[newDict setObject:receipt.receita_atualizada forKey:#"receita_atualizada"];
[arrayTemp addObject:newDict];
NSLog(#"%#", arrayTemp); // shows me the array of dicts
// until here, its ok!
}];
}
NSLog(#"%#", arrayTemp); // shows me an empty array...F*CK!
Initialise your arrayOfDict.
NSMutableArray * arrayOfDict = [[NSMutableArray alloc] init];
The array is empty because you are not initialising it. write this above line at the top and then add
[arrayOfDict arrayWithObjects: <UR ITEMS>];
Hope it works..!! Happy Coding
I am new to iOS and want to create an NSArray like this which contains an NSDictionary.
[
{
Image: 1, 2,3
Title: 1,2,3
Subtitle:1,2,3
}
]
I have tried this.
NSArray *obj-image=#[#"Test.png",#"Test.png",#"Test.png"];
NSArray *obj-title=#[#"Test",#"Test",#"Test"];
NSArray *obj-subtitle=#[#"Test",#"Test",#"Test"];
NSDictionary * obj_dictionary ={ image : obj_image, title:obj_title, subtitle:obj_subtitle}
NSArray * obj_array= [obj_dictionarry];
But not working and how to access them.
First of all, you initialization of Arrays and Dictionaries is wrong. You cannot use "-" in the names, period.
Second, you need to allocate and then initialize the objects. This is how you do that with arrays:
NSArray *images = [NSArray arrayWithObjects: #"TestImage",#"TestImage",#"TestImage",nil];
NSArray *titles = [NSArray arrayWithObjects: #"TestTitle",#"TestTitle",#"TestTitle",nil];
NSArray *subtitles = [NSArray arrayWithObjects: #"TestSubTitle",#"TestSubTitle",#"TestSubTitle",nil];
Then you need Mutable dictionary and mutable arrays to work with the data (mutable means you can change the values inside, add or remove objects etc.)
This is the most basic example of what you are trying to achieve:
NSArray *images = [NSArray arrayWithObjects: #"TestImage",#"TestImage",#"TestImage",nil];
NSArray *titles = [NSArray arrayWithObjects: #"TestTitle",#"TestTitle",#"TestTitle",nil];
NSArray *subtitles = [NSArray arrayWithObjects: #"TestSubTitle",#"TestSubTitle",#"TestSubTitle",nil];
NSMutableArray *objectsMutable = [[NSMutableArray alloc] init];
for (NSString *string in images) {
NSMutableDictionary *dictMutable = [[NSMutableDictionary alloc] init];
[dictMutable setObject:string forKey:#"image"];
//determining the index of the image
NSInteger stringIndex = [images indexOfObject:string];
[dictMutable setObject:[titles objectAtIndex:stringIndex] forKey:#"title"];
[dictMutable setObject:[subtitles objectAtIndex:stringIndex] forKey:#"subtitle"];
NSDictionary *dict = [[NSDictionary alloc] init];
dict = dictMutable;
[objectsMutable addObject:dict];
}
NSArray *objects = objectsMutable;
NSLog(#"%#", objects);
Hope this helps.
As you can see, I'm going through the images array, capturing the index of each one, an then just apply values of other arrays from the same index into a mutable dictionary.
All I do after that is just make a regular dictionary and array to put the data inside. This is ho the Log will look:
(
{
image = TestImage;
subtitle = TestSubTitle;
title = TestTitle;
},
{
image = TestImage;
subtitle = TestSubTitle;
title = TestTitle;
},
{
image = TestImage;
subtitle = TestSubTitle;
title = TestTitle;
}
)
You have an array with three objects inside, each with their own image, title and subtitle.
Here is code :
NSMutableArray *array = [[NSMutableArray alloc] init];
NSMutableDictionary *mdict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"object1",#"key1",#"object2",#"key2",nil];
[array addObject:mDict];
so now if u need to access dictionary from array then :
NSMutableDictionary *mDict1 = [array objectatindex:0];
NSLog(#"%#",[mDict1 valueForkey:#"key1"];
--> print object 1.
This is the way to store array of dictionaries:
NSDictionary *dic=#{#"kishore":#"hai"};
NSMutableArray *arr=[[NSMutableArray alloc]init];
[arr addobject:dic];
this is the way to get those values:
[arr objectforkeyValue #"kishore"];
NSMutableArray *dictArray = [[NSMutableArray alloc] init]; // created and initiated mutable array
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; // created and initiated mutable Dictionary
[dict setObject:#"object1" forKey:#"1"]; // added a key pair in dictionary (you can set multiple objects)
[dictArray addObject:dict]; // added dictionary to array (you can add multiple dictionary to array )
NSLog(#"dictionary inside an array : %#",dictArray[0][#"1"]); // access dictionary from array
You can try something like this
[NSArray arrayWithObjects:#{#"Image":#[#1,#2,#3]},#{#"Title":#[#1,#2,#3]},#{#"SubTitle":#[#1,#2,#3]}, nil];
You can easily create objects of array and access them back using following way.
NSArray *objimage=#[#"Test1.png",#"Test2.png",#"Test3.png"];
NSArray *objtitle=#[#"Test1",#"Test2",#"Test3"];
NSArray *objsubtitle=#[#"Test1",#"Test2",#"Test3"];
NSDictionary *obj_dictionary = #{#"image":objimage,#"Title":objtitle, #"subtitle":objsubtitle};
NSArray * obj_array= [[NSArray alloc] initWithObjects:obj_dictionary, nil]; // Create Array of nested objects
if([obj_array count] > 0) {
NSArray * imageArray = obj_array[0][#"image"]; // Access the nested objects in Array.
NSLog(#"%#", imageArray[0]);
}
first of all u need to declare correct variable name
NSArray *objImage=#[#"Test.png",#"Test.png",#"Test.png"];
NSArray *objTitle=#[#"Test",#"Test",#"Test"];
NSArray *objSubtitle=#[#"Test",#"Test",#"Test"];
at this point all u are created all the array, and u need to create dictionary like below
NSDictionary *obj_dictionary = #{#"image":objImage,#"title":objTitle, #"subtitle":objSubtitle};
// NSArray * obj_array = obj_dictionary[#"image"];
NSArray * obj_array = #[obj_dictionary]; //u can crate array of dictionary like this
in above obj_dictionary will contains all the array like below,
Title = (
Test,
Test,
Test
);
image = (
"Test.png",
"Test.png",
"Test.png"
);
subtitle = (
Test,
Test,
Test
);
and u can access the object in the dictionary like below using a key for example
NSArray * obj_array_images = obj_dictionary[#"image"];
gives an array of images that is associated with key image, similarly u can access other array like this by providing different keys associated with the dictionary obj_dictionary for example
NSArray * obj_array_titles = obj_dictionary[#"title"];
NSArray * obj_array_subtitles = obj_dictionary[#"subtitle"];
edit
NSArray *objImage=#[#"Test.png",#"Test.png",#"Test.png"];
NSArray *objTitle=#[#"Test",#"Test",#"Test"];
NSArray *objSubtitle=#[#"Test",#"Test",#"Test"];
NSDictionary *obj_dictionary = #{#"image":objImage,#"title":objTitle, #"subtitle":objSubtitle};
// NSArray * obj_array = obj_dictionary[#"image"];
NSArray * obj_array = #[obj_dictionary]; //u can crate array of dictionary like this