NSDictionary with key => String and Value => c-Style array - iphone

I need an NSDictionary which has key in the form of string (#"key1", #"key2") and value in the form of a C-style two-dimensional array (valueArray1,valueArray2) where valueArray1 is defined as :
int valueArray1[8][3] = { {25,10,65},{50,30,75},{60,45,80},{75,60,10},
{10,70,80},{90,30,80},{20,15,90},{20,20,15} };
And same for valueArray2.
My aim is given an NSString i need to fetch the corresponding two-dimensional array.
I guess using an NSArray, instead of c-style array, will work but then i cannot initialize the arrays as done above (i have many such arrays). If, however, that is doable please let me know how.
Currently the following is giving a warning "Passing argument 1 of 'dictionaryWithObjectsAndKeys:' from incompatible pointer type" :
NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:valueArray1,#"key1",
valueArray2,#"key2",nil];

Is valueArray2 also an int[][3]? If so, you could use
[NSValue valueWithPointer:valueArray1]
to convert the array into an ObjC value. To retrieve the content, you need to use
void* valuePtr = [[myDict objectForKey:#"key1"] pointerValue];
int(*valueArr)[3] = valuePtr;
// use valueArr as valueArrayX.
If there's just 2 keys, it is more efficient to use a function like
int(*getMyValueArr(NSString* key))[3] {
if ([key isEqualToString:#"key1"]) return valueArray1;
else return valueArray2;
}

Rather than Adding Array Directly as a value in NSDictionary make a custom class in which create variable of NSArray ... and set this class object as value like
NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:MyClassObj1,#"key1",
MyClassObj2,#"key2",nil];
where MyClassObj1 and MyClassObj2 are member of MyClass

Related

A question about NSDictionary initialization

the result is 4 2 3, but what happened in the process of initialization of this NSDictionary?
it's because that its assignment just execute at first time and ignore the rest assignment to same key? Or it's because that its assigment execute with Reverse order?
NSDictionary *dic = #{
#"a":#"4",
#"b":#"2",
#"c":#"3",
#"a":#"1",
#"b":#"5",
#"c":#"6",
};
NSLog(#"luozhiyong,%#",dic[#"a"]);
NSLog(#"luozhiyong,%#",dic[#"b"]);
NSLog(#"luozhiyong,%#",dic[#"c"]);
From the documentation of NSDictionary:
NSDictionary A static collection of objects associated with unique keys.
In addition to the provided initializers, such as initWithObjects:forKeys:, you can create an NSDictionary object using a dictionary literal.
NSDictionary *dictionary = #{
#"anObject" : someObject,
#"helloString" : #"Hello, World!",
#"magicNumber" : #42,
#"aValue" : someValue
};
In Objective-C, the compiler generates code that makes an underlying call to the dictionaryWithObjects:forKeys:count: method.
From the documentation of dictionaryWithObjects:forKeys:count:
This method steps through the objects and keys arrays, creating entries in the new dictionary as it goes.
The result of
NSDictionary *dic = #{
#"a":#"4",
#"b":#"2",
#"c":#"3",
#"a":#"1",
#"b":#"5",
#"c":#"6",
};
is unpredictable and may be different in other versions of Foundation. On macOS 10.13.6 the duplicate keys are ignored.

Saving enum values into a dictionary

How does one save an enum value to a dictionary?
When I try the following
enum someEnum
{
field0 = 0,
field1 = 1,
field2 = 2,
};
enum someEnum someEnumObject;
and I try to save it to a dictionary using
[NSDictionary dictionaryWithObjectsAndKeys:]
someEnumObject, #"enum",
I get this
warning: Semantic Issue: Incompatible integer to pointer conversion sending 'enum behaviour' to parameter of type 'id'
Use the following to save it to dictionary,
[NSNumber numberWithInt:enumValue], #"enum",
And you can retrieve it as,
enumValue = [[dictionary valueForKey:#"enum"] intValue];
Better use NSNumber literals to convert an enum to an object so that it can be stored in NSDictionary:
[NSDictionary dictionaryWithObjectsAndKeys:#(someEnumObject), #"enum", nil];
Literals provide shorthands to write stuff, this dictionary can be written like:
#{#"enum":#(someEnumObject)};
Read more about literals here:
http://clang.llvm.org/docs/ObjectiveCLiterals.html
An enum is essentially an integer and an NSDictionary stores objects, so you need to convert your enum to an object. An NSNumber would work well for this:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:someEnumObject], #"enum", nil];
In modern times #(enumValue) is the easier approach.

method with many parameters

i have a method with 20 parameters,( NSString, float,....), can i construct a type ( for example Enumerated, typdef) to invoque my method and not pass all my parameters ?
replace:
-(void)myMethodeParam1:...:param2:.... ;
with:
-(void)myMethode:MyNewTypeParam ;
tanks for your answers
You can use NSDictionary (NSMutableDictionary). You'll need to wrap primitive type (like float) to obj-c objects (e.g. NSNumber) for that though.
E.g. you have 10 NSString params named param0,...,param9 then you can place them in NSDictionary:
NSDictionary *paramDict = [NSDictionary dictionaryWithObjectsAndKeys:string0, #"param0", string1, #"param1", ..., string9, #"param9", nil];
[obj myMethod: paramDict];
or if you can enumerate your variables somehow you can use NSMutableDictionary and add them to it in a loop.
Then in your method you can get your parameters from dictionary you have:
-(void)myMethode: (NSDictionary*)dict{
NSString *string0 = [dict objectForKey:#"param0];
//Do something with it
...
}
If your parameters together are some logical entity and they're usually used together you also can also create a custom class that contains them as instance variables

NSDictionary with integer as number

I have a NSDictionary with the following layout:
{
1:{
... some data ...
}
...
}
I have a NSNumber object with a integer value of 1, but when I do
[my_dict objectForKey:my_number] it returns null.
If I try and convert NSNumber to a integer via [my dict objectForKey:[my_number intValue]] I get a warning and the program crashes when it reaches that part of the code.
Any help would be greatly appreciated.
Keys in a NSDictionary or NSMutableDictionary must be objects, like NSNumber. They cannot be primitive data types, like int.
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html
Looks like you're trying to use an integer as the key in your NSDictionary. This would be correct with an NSArray, with an NSDictionary actually needs a proper object as a key.
You might have more success in this particular case feeding that data into an NSArray, and accessing it with:
id *someData = [my_array objectAtIndex:1];

What kind of data is in an "enum" type constant? How to add it to an NSArray?

What kind of information is stored behind such an enum type thing? Example:
typedef enum {
UIViewAnimationCurveEaseInOut,
UIViewAnimationCurveEaseIn,
UIViewAnimationCurveEaseOut,
UIViewAnimationCurveLinear
} UIViewAnimationCurve;
I am not sure if I can safely add such an enum constant to an array. Any idea?
Enums in Objective-C are exactly the same as those in C. Each item in your enum is automatically given an integer value, by default starting with zero.
For the example you provided: UIViewAnimationCurveEaseInOut would be 0; UIViewAnimationCurveEaseIn would be 1, and so on.
You can specify the value for the enum if required:
typedef enum {
UIViewAnimationCurveEaseInOut,
UIViewAnimationCurveEaseIn = 0,
UIViewAnimationCurveEaseOut,
UIViewAnimationCurveLinear
} UIViewAnimationCurve;
This result of this would be: UIViewAnimationCurveEaseInOut is 0; UIViewAnimationCurveEaseIn is 0; UIViewAnimationCurveEaseOut is 1; and so on. However, for basic purposes you shouldn't need to do anything like that; it just gives you some useful info to toy with.
It should be noted based on the above, that an enum can't assume to be a unique value; different enum identifiers can be equal in value to each other.
Adding an enum item to a NSArray is as simple as adding an integer. The only difference would be that you use the enum identifer instead.
[myArray addObject:[NSNumber numberWithInt:UIViewAnimationCurveEaseInOut]];
You can check this out for yourself by simply outputting each enum to the console and checking the value it provides you with. This gives you the opportunity to investigate the details of how it operates. But for the most part you won't really need to know on a day to day basis.
Enums are typically int values. You can store them in an array by wrapping them in an NSNumber:
[myMutableArray addObject:[NSNumber numberWithInt:myAnimationCurve]];
... then get them back out like this:
UIViewAnimationCurve myAnimationCurve = [[myMutableArray lastObject] intValue];
Enums in Objective-C are the same as enums in vanilla C. It's just an int. If you're using an NSArray, then it expects a pointer and you'll get a warning if you try to add an int to it:
NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:UIViewAnimationCurveEaseInOut];
// Last line results in:
// warning: passing argument 1 of 'addObject:' makes
// pointer from integer without a cast
If you're storing a large collection of 32-bit integers, consider using the appropriate CF collection type rather than the NS collection type. These allow you to pass in custom retain methods, which gets rid of the need to box every integer added to the collection.
For example, let's say you want a straight array of 32-bit ints. Use:
CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
The last parameter tells the array to not retain/release the "addresses" you pass in to it. So when you do something like this:
CFArrayAppendValue(arrayRef, 1);
What the array thinks is that you're passing in a pointer to an object living at the memory address 0x1. But since you told it to not call retain/release on that pointer, it gets treated as a standard int by the collection.
FWIW, for educational value, standard NSMutableArrays have equivalent CF types. Through toll-free bridging you can use the CF collection as a standard Foundation collection:
CFMutableArrayRef arrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, kCFTypeArrayCallbacks);
NSMutableArray *array = (NSMutableArray *)arrayRef;
[array addObject:#"hi there!"];
NSLog(#"%#", [array objectAtIndex:0]); // prints "hi there!"
You can apply the same tricks to dictionaries (with CFDictionary/CFMutableDictionary), sets (CFSet/CFMutableSet), etc.