How to use setValue:forKey: function with NSArray - iphone

I'm try to use the functions -setValue:forKey: and get the value using -valueForKey:
Example:
NSArray *rootarr = [[NSArray alloc] init];
NSArray *array = [[NSArray alloc] initWithObjects:#"name", #"address", #"title", nil];
[rootarr setValue:array forKey:#"n"];
NSArray *getArr = [rootarr valueForKey:#"n"];
But the getArr array I got is not equal the array I set (array).
Could you please tell me what's wrong I met. And what's the way to use these functions?

NSArray's setValue:forKey: method is used for Key Value Coding, not for using an array as an associative container. You need to use NSMutableDictionary.
NSMutableDictionary *rootDict = [NSMutableDictionary dictionary];
NSArray *array = [[NSArray alloc] initWithObjects:#"name", #"address", #"title", nil];
[rootDict setValue:array forKey:#"n"];
NSArray *getArr = [rootDict valueForKey:#"n"];

An array isn't a key-value store, which you appear to want to use it as. I think you want an NSDictionary instead (or more precisely NSMutableDictionary if you want to modify it after its created).

According to the Apple documentation setValue:forKey:
Invokes setValue:forKey: on each of the array's items using the specified value and key.
Practical uses are when you want to set the same value to each element of the array
UILabel *label1 = [[UILabel alloc]init];
UILabel *label2 = [[UILabel alloc]init];
NSArray *arr = #[label1, label2];
[arr setValue:#"bye" forKey:#"text"];
NSLog(#"%# %#",label1.text, label2.text); // bye bye
in your example "getArr" is an empty array because your "rootarr" doesn't have elements, otherwise you receive a setValue:forUndefinedKey: into the contained objects that are not compliant for the assigned key

You can't add objects to an NSArray after it is created. You have to use NSMutableArray in order to do that.

Related

How to set array value and key in NSDictionary in iphone?

Here i am using NSMutableArray to store date, then i tried to set key and assign ArrayValue in dictionary but the app crashed, please help me
Thanks in ADvance
Here i tried the code for your reference:
[DateArray addObject:dateString]; //NSMutablArray
NSMutableDictionary *myDictionary =[[NSMutableDictionary alloc]init];
[myDictionary setObject:DateArray forKey:#"Date"]; //put array value and set key in NSDictionary.
NSDictionary Class is immutable. You must convert to NSMutableDictionary.
If you are using XCode version 4.4 or later you can jus do this:
[dateArray addObject:dateString]; //NSMutablArray
NSDictionary *myDictionary = #{ #"Date", dateArray };
You are using NSDictionary. You should use NSMutableDictionary.
NSDictionary is immutable. If you want to use NSDictionary then use below method:
- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
You're using an NSDictionary when you should be using NSMutableDictionary
Try this line :
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
Most of the collection classes in iOS have a mutable and nonmutable version (i.e.
NSArray -> NSMutableArray
NSSet -> NSMutableSet
NSDictionary -> NSMutableDictionary
(and others)
A mutable version will let you modify the contents. However, if you know you're not going to change it then a non mutable version will be slightly faster to use.
You can (usually) get a mutable class from a nonmutable one by using the mutableCopy method i.e.
// This array can't be changed
NSArray *myArray = #[ #"A", #"B", #"C" ];
// This array contains everything from the previous array but can now be modified
MSMutableArray myArray2 = [myArray mutableCopy];
NB : There are also other classes that have mutable subclasses i.e. NSURL -> NSMutableURL
Do it like this:
for(int i=0;i<[DateArray count]; i++)
{
[myDictionary addObject:[DateArray objectAtIndex:i] forKey:#"Date"];
}

Add dynamically created string to an array

I am making an iphone app in which I want to store the dynamically selected time into an array, but unable to implement the method to store the strings into an array. Following is the code which I am using but it is not giving the output.
- (void)storetimeintoanarray:(id)sender
{
NSDateFormatter *df3 = [[NSDateFormatter alloc] init];
[df3 setDateFormat:#"hh:mm:ss"];
timestr = [NSString stringWithFormat:#"%#",[df3 stringFromDate:objtimepicker.date]];
NSLog(#"time is:%#",timestr);
test = [[NSArray alloc]init];
[test arrayByAddingObject:timestr];
NSLog(#"array time:%#",test);
}
You have to declare array mutable object.
test = [[NSMutableArray alloc]init];
[test addObject:timestr];
You have to assign the result of the arrayByAddingObject: method to a new array like:
NSArray *newone = [test arrayByAddingObject:timestr];
After allocating you shouldn't allocate the array again. arrayByAddingObject returns a auto released new array. Also use a NSMutableArray when you want to add objects dynamically.
Change the code to
test = [[NSMutableArray alloc]init];
[test addObject:timestr];
You should be using NSMutableArray if you want to change it after creation.
NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:timestr];
To create an array with a single object, you can use:
NSArray* arr = [NSArray arrayWithObject:timestr];
You should use NSMutableArray and its method addObject: instead of NSArray. [test arrayByAddingObject:timestr]; does nothing with your array test, its create new array

iPhone: How to access NSMutableArray two dimensional setting?

I am using insertObject for NSMutableArray for storing values into two dimensional array like below for example.
[mutableArrayPtr insertObject:[NSMutableArray arrayWithObjects:firstData, secondData,nil] atIndex:index];
I think, it is correct way of storing values in two dimensional array in Obj C.
I want to access it at later point of time. How can i do that?
Thanks!
The way you are doing it is perfectly fine. NSArray's don't have native two dimensional syntax like primitive arrays (int[][], double[][], etc.) in C do. So instead, you must nest them using an array of arrays. Here's an example of how to do that:
NSString *hello = #"Hello World";
NSMutableArray *insideArray = [[NSMutableArray alloc] initWithObjects:hello,nil];
NSMutableArray *outsideArray = [[NSMutableArray alloc] init];
[outsideArray addObject:insideArray];
// Then access it by:
NSString *retrieveString = [[outsideArray objectAtIndex:0] objectAtIndex:0];
To access your array at a later point in time, you would do something like:
NSArray* innerArray = [mutableArrayPtr objectAtIndex:0];
NSObject* someObject = [innerArray objectAtIndex:0];
Of course, change 0 to whatever index you actually need to retrieve.
EDIT:
Q: Is it "initWithObjects" (or) "insertObject:[NSMutableArray arrayWithObjects:imagePtrData,urlInStr,nil]" for two dimension?
A: initWithObjects and insertObject would both allow you to create two dimensional arrays. For example you could do:
NSMutableArray* arrayOne = [[NSMutableArray alloc] initWithObjects:[NSArray initWithObjects:#"One", #"Two", #"Three", nil], [NSArray initWithObjects:[#"Four", #"Five", #"Six", nil], nil];
// NOTE: You need to release the above array somewhere in your code to prevent a memory leak.
or:
NSMutableArray* arrayTwo = [NSMutableArray array];
[arrayTwo insertObject:[NSArray arrayWithObjects:#"One", #"Two", #"Three", nil] atIndex:0];

Difference between the following allocations types?

I have a simple code:
NSMutableArray *arrayCheckList = [[NSMutableArray alloc] init];
[arrayCheckList addObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:#"2011-03-14 10:25:59 +0000",#"Exercise at least 30mins/day",#"1",nil] forKeys:[NSArray arrayWithObjects:#"date",#"checkListData",#"status",nil]] ];
[arrayCheckList addObject:[NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:#"2011-03-14 10:25:59 +0000",#"Take regular insulin shots",#"1",nil] forKeys:[NSArray arrayWithObjects:#"date",#"checkListData",#"status",nil]]];
Now I want to add a specific index of above array to a dictionary. Below are two way, which one is better and why? What are the specific drawbacks of the latter?
NSDictionary *tempDict = [[NSDictionary alloc] initWithDictionary:[arrayCheckList objectAtIndex:1]];
OR
NSDictionary *tempDict = [arrayCheckList objectAtIndex:1];
What would the impact on the latter since I am not doing any alloc/init in it?
1:
NSDictionary *tempDict = [[NSDictionary alloc] initWithDictionary:[arrayCheckList objectAtIndex:1]];
Creates a new immutable dictionary object as a copy of the original one. If you add objects to the mutable dictionary in your arrayCheckList they will not be added to your copied reference.
2:
NSDictionary *tempDict = [arrayCheckList objectAtIndex:1];
This directly pulls the mutable dictionary from your array and not a copy. The following two lines will be equivalent:
[[arrayCheckList objectAtIndex:1] addObject:something];
[tempDict addObject:something];
The first one potentially copies the dictionary a index 1 of the array. (It should, since you're creating an immutable dictionary but the one in the array is mutable.) The second only gets a reference to the dictionary in the array -- there's no chance of creating a new object.

Creating a Two-Dimensional Array with Concrete Positions

I need to create a custom array:
In php I would define as follows:
$myarray[100][80] = 1;
But I don't know how to do it in objective-c...
I don't need an array [0][0],[0][1],[0][2], ... I only need concrete positions in this array [80][12], [147][444], [46][9823746],...
The content of these positions always will be = 1;
for this you would use a dictionary rather than an array as they are always 0,1,2 keyed so something along the lines of:
NSNumber *one = [NSNumber numberWithInt:1];
NSString *key = #"80,12";
NSDictionary *items = [NSDictionary dictionaryWithObject:one forKey:key];
Then to pull them out again you would use the objectForKey: method.
You cannot put ints directly into arrays or dictionaries that's why it is wrapped in the NSNumber object. To access the int after getting the NSNumber out of the dictionary you would use something like:
NSNumber tempNum = [items objectForKey:key];
int i = tempNum.intValue;
See the docs here for a full explanation of the NSDictionary class. Hope this helps...
I an not a PHP master but I believe in php arrays are not real arrays they are hash tables right?
Anyway, I think you are looking for NSDictionary or NSMutableDictionary class.
That looks more like a bitset than an array.
Allocating so many cells for that seems useless, so maybe you could revert the problem, and store the positions in an array.
Well in objective c we can use NSMutableArray to define 2-D arrays.
See the following code, it might help you
NSMutableArray *row = [[NSMutableArray alloc] initWithObjects:#"1", #"2", nil];
NSMutableArray *col = [[NSMutableArray alloc] init];
[col addObject:row];
NSString *obj = [[col objectAtIndex:0] objectAtIndex:0];
NSLog(#"%#", obj);