adding Char or NSString into Objective C enum - ios

I have created an enum in my header file that looks like this
typedef enum {stTMD = 1, stT2MD = 2, stDCMD = 'D', stMBMD = 'M'} stTypes;
First off I am not even sure if thats the correct way to declare a char in an enum but
As you can see some values are integers and others are chars. However I am getting the following error when I try to place these values into a NSDicitonary like this
NSDictionary *iCTypes = [[NSDictionary alloc] initWithObjectsAndKeys:stDCMD,#"stMB", stMBMD,#"stMBMD", nil];
but I am getting this error below
Implicit conversion of 'int' to 'id' is disallowed with ARC
any help would be greatly appreciated.

An enum is basically an int type. Your enum definition is just fine. The problem is your use in the dictionary. You need to wrap the enum values in an NSNumber.
Try:
NSDictionary *iCTypes = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:stDCMD], #"stMB", [NSNumber numberWithInt:stMBMD] ,#"stMBMD", nil];
or even better (using modern Objective-C):
NSDictionary *icTypes = #{ #(stDCMD) : #"stMB", #(stMBMD) : #"stMBMD" };

You need to store objects inside it, so you can't store an int, rather a NSNumber, which can be made by appending a # before the number constant:
NSDictionary *iCTypes = [[NSDictionary alloc] initWithObjectsAndKeys: #(stDCMD),#"stMB", #(stMBMD),#"stMBMD", nil];
However a clarification is needed on this:
First off I am not even sure if thats the correct way to declare a char in an enum but As you can see some values are integers and others are chars.
When you define an enum it stores integers, it doesn't matter if you set chars as values, they're compatible with int so the compiler will not complain. But the storage type is the same, they're still integers and any type compatible with integers will be accepted.

Both the objects and keys in an NSDictionary must be objects, and the keys specifically must be objects that conform to NSCopying. In order to use ints in an NSDictionary, you have to convert them to NSNumbers. You can use either [NSNumber numberWithInt:stDCMD] or, if you're using a newer version of Xcode, #(stDCMD).

In C char is a kind of short int.
enum can only hold integer types.
NSDictionary cannot hold C types. Only objects.
You can wrap your C types in NSValue or NSNumber to put in an NSDictionary.

Related

IOS/Objective-C: Get Number from JSON

I have a JSON dictionary that contains what I will call an integer (in mathematics) i.e. 1.
I would like to save this number to a core data attribute that is an NSInteger. The following code is issuing warning:
Incompatible Pointer to Integer Conversion initializing NSInteger with an expression of type 'id'
NSInteger insertID = jsonResults[#"insert_id"];
I have tried various combinations of int, NSNumber, etc. to no avail. Can anyone suggest right way to do this?
NSDictionary can't store NSInteger. It is storing NSNumber. So you need to unwrap the NSNumber:
NSInteger insertID = [jsonResults[#"insert_id"] integerValue];
in core data you should save numeric value as Number Type.
For eaxample,
To save:
insert_id = #(100)//say 100 is your insert_id value
To read:
NSInteger insertID = [jsonResults[#"insert_id"] intValue];

Xcode, ios, Set name of variable to value of another variable?

I want to set the name of a variable to the value of another variable are there any other ways to do this because I don't think this is the way.
NSString *myint = #"a";
NSString *([NSString stringWithFormat:#"%#", myint]) = #"something";
NSLog(#"%#", a);
No, you can't do that. Once your code is compiled, your variables don't really have names -- just locations. The names you see in the debugger are provided by a symbol file which the debugger uses to map locations to names.
Key-value coding could help, depending on what you're really trying to accomplish. With KVC, you use key names to refer to values rather than accessing variables, much as you do with a dictionary. For example, if you have an object with properties foo and bar, you can then do something like this:
NSString *key = #"foo";
[myObject setValue:#(5) forKey:key];
You could even override -setValue:forKey: so that it accepts any key and remembers the value (which is exactly what a dictionary does).
You can go in the other direction (set a variable to the name of another variable) using the stringification operator, but it's kinda hacky and not usually all that useful. In a nutshell, macro parameters prefixed with a # are used as literal strings instead of being evaluated. So you'd create a macro like this:
#define string(x) #x
and then you'd use it somewhere in your code like this:
int foo = 5;
NSLog("The name of the variable is %s and its value is %d.", string(foo), foo);
with the following result:
The name of the variable is foo and its value is 5.
I agree with Paulw11. You could define a NSMutableDictionary to hold all your variables by key. I don't think there is any way the compiler can use a handle determined at runtime. But you can achieve the same affect.
So say, for instance, that both the variable handle and value were NSString, then you could do something like this.
NSMutableDictionary *myObjects = [[NSMutableDictionary dictionary] init];
NSString variableName = #"myString";
[myObjects setObject #"Variable value" forKey: variableName];
NSLog("Variable %# has value %#.", variableName, [myObjects objectForKey: variableName]);

iOS converting value in NSDictionary with (int) fail

I had a NSDictionary contains 2 key/value pairs:
NSDictionary *dic = #{#"tag":#2, //NSNumber
#"string":#"someString"}; //NSString
NSLog(#"%i",(int)[dic objectForKey:#"tag"]); //print out 34
NSLog(#"%i",[dic objectForKey:#"tag"] intValue]); //print out 2
Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?
Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?
id is a pointer type. id pointers point to Objective-C objects in memory. By casting id to (int), you are merely reinterpreting (some of) the pointer's bit pattern as an int, which is quite meaningless. You have to call the proper conversion methods of NSString and NSNumber if you want to reliably get the primitive values out of the Objective-C object.
If you ever seemingly get the "correct" value of 2 in the case of pointer-casting with NSNumber, that may be because the Objective-C runtime makes use of an optimization technique called tagged pointers, whereby small objects are not really created and allocated, but their semantics (the number's bits which the NSNumber object stores) is stuffed into the unused bits of the pointer.
#2 is not an int but a NSNumber you can't cast an NSNumber into an int. You have to use intValue method to get the correct result.
The method objectForKey: returns a pointer to the NSNumber object #2, not the value stored in the object itself. So you're typecasting the pointer, not the value 2. In the last line you don't typecast the object but you access a property called intValue which returns the value of the object expressed as an int.
NSDictionary contains Object with Key value pairs,but you passed int(#2) into object
NSDictionary *dic = #{#"tag":#2, //NSNumber
#"string":#"someString"};
so Change int to NSNumber like
NSDictionary *dic = #{#"tag":[NSNumber numberWithInt:2];,#"string":#"someString"};
and you can get it..
int number = [[dict objectForKey:#"tag"] intValue];

Float array to float *

What is the difference between float[] and float*?
Also, how can I convert a float array to float *? I need to get a float * and open it, then apply a filter and send it as a float * into my FFT method, but I don't know how to do it because I don't know the real difference between them.
An array usually is a pointer to the first member of the list. When using Array[Identifier], you are accessing to *(p+Identifier).
Making a new array will define a series of pointer next to another, which will make it's use way easier.
You can set your float array in the following ways:
float array1[100] = { 0 };
float *dataArray = (float*)malloc(sizeof(float) * 100);
float *pointerToFloatArray = array1;
These points all relate to C:
the name of an array can be decomposed — i.e. implicitly converted — to a pointer to its first element;
in an array, elements are stored contiguously;
the syntax a[8] is just shorthand for *(a + 8); and
adding n to a pointer, p, is defined to add n * sizeof(*p).
So an array differs from a pointer by being a semantically different thing. But you can supply the name of an array anywhere a pointer is required as it'll be converted.
Separately, you can also add an offset to any pointer using subscript syntax.
Objective-C is a strict superset of C. So these rules also apply to the use of the primitive types in Objective-C.
To understand the distinction, think in terms of mutability. The following is invalid:
char array[];
char value;
array = &value;
You can't reassign array. It is the name of an array. array itself is not mutable at runtime, only the things within it are. Conversely the following is valid:
char *pointer;
char value;
pointer = &value;
You can reassign pointer as often as you like. There's a mutable pointer and you can use it to point to anything.
You can use C-style arrays, like described in this answer: https://stackoverflow.com/a/26263070/3399208,
but better way - is using Objective-C containers and Objective-C objects, for example NSNumber * :
NSArray *array = [#1, #2, #3];
or
NSMutableArray *array = [NSMutableArray array];
NSNumber *number1 = [NSNumber numberWithFloat:20.f];
NSNumber *number2 = #(20.f);
[array addObject:number1];
[array addObject:number2];

ios assigning value to a string from an array

So I have a basic array:
NSMutableArray *answerButtonsArrayWithURL = [NSMutableArray arrayWithObjects:self.playView.coverURL1, self.playView.coverURL2, self.playView.coverURL3, self.playView.coverURL4, nil];
The objects inside are strings. I want to access a random object from that array
int rndValueForURLS = arc4random() % 3;
and assigning it a value. I've tried manny different approaches but my recent one is
[[answerButtonsArrayWithURL objectAtIndex:rndValueForURLS] stringByAppendingString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
Any help will be much appreciated. Thanks
You need to assign it. You're already building the new value like that:
NSString *oldValue = answerButtonsArrayWithURL[rndValueForURLS];
NSString *newValue = [oldValue stringByAppendingString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
The part you're missing :
answerButtonsArrayWithURL[rndValueForURLS] = newValue;
Above would be the way to replace the immutable string with another. If the strings are mutable, that is, they were created as NSMutableString, you could do:
NSMutableString *value = answerButtonsArrayWithURL[rndValueForURLS];
[value appendString:[self.coverFromRightAnswer objectAtIndex:self.rndValueForQuestions]];
Note:
Everywhere I replace the notation :
[answerButtonsArrayWithURL objectAtIndex:rndValueForURLS];
with the new equivalent and IMO more readable:
answerButtonsArrayWithURL[rndValueForURLS];

Resources