Array of enums - convert to NSArray - objective-c

Having
enum {MyA, MyB, Null};
typedef NSNumber myEnum;
Or
typedef enum {MyA, MyB, Null} myEnum;
1) How do I create an array
myEnum* myEnumTemp[] = {MyA, MyB};
Just gives "Implicit conversion of 'int' to NSNumber* is disallowed with ARC(ref. counting)
2) If you are able to create an array how to convert it to NSArray?

Try to do it this way :
typedef enum { MyA, MyB, Null } myEnum;
Then, to create an array, wrap the numbers into NSNumbers objects :
NSArray *a = [NSArray arrayWithObjects:[NSNumber numberWithInteger:MyA],
[NSNumber numberWithInteger:MyB],
nil];

In Obj C:
enumArray = #[#(enum1),#(enum2)];
In Swift:
enumArray = NSArray(objects: enum1.rawValue, enum2.rawValue);

Basically, you need to wrap the value in a NSNumber object.
#define INT_OBJ(x) [NSNumber numberWithInt:x]
[array addObject:INT_OBJ(MyA)];
And there was nothing wrong with your other array, you just should have defined it like this:
typedef enum {MyA, MyB, Null} myEnum;
myEnum values[] = { MyA, MyB };
The problem was that you defined myEnum as a NSNumber, which is not equal to an enum value (int).

Related

Storing and retrieving enums from NSArray

I'm a beginner obj-c programmer. I want to store enums in an NSMutableArray, then retrieve them.
I do this by first converting the enum to NSNumber object then storing that object into the array, and then retrieving it and converting it back to an integer. I have code that does it without arrays, and works, but I need to use an array.
Code:
//What I am trying to do:
NSNumber *n = [NSNumber numberWithInt:west];
[DirectionList addObject:n];
Direction intendedDirection = [[DirectionList objectAtIndex:0] intValue];
if (intendedDirection == west)
{
exit(-1); // DOES NOT EXIT, BUT SHOULD
}
//This code works, though
NSNumber *n = [NSNumber numberWithInt:west];
Direction intendedDirection = [n intValue];
if (intendedDirection == west)
{
exit(-1); // EXITS AS EXPECTED
}
Any ideas why the 1st one doesn't work?
Thanks.
If you don't need to mutate the array, I suggest you this method which is much, much cleaner than the one you're trying to follow.
I'm using NSString for this example but you can use any object you want
typedef NS_ENUM(NSUInteger, Direction) {
North,
South,
West,
East
};
NSString *const directionDescriptions[] = {
[West] = #"West",
[East] = #"East",
[North] = #"North",
[South] = #"South",
}
Then you can access your description using the enum as the index of this array.
// E.g.
NSSLog(#"%#", directionDescriptions[West]); // #"West"

Pointer Variable (*) and Double Pointer (**) Usage With Classes in Objective C

int a=1;
int * b;
b = &a;
int **c=&b;
In Objective-C, the Pointer (*) variable is used for primitive data types as well with classes like NSString, NSError etc...
NSString *str = #"iOS"; // or NSString *str= [[NSString alloc] initWithString : #"iOS"];
NSArray *arr =[[NSArray alloc] init];
I have seen in Objective-C (NSError **) what is use of double pointer objects for classes in Objective-C?
There is no such thing as a "double pointer". If you call it a "double pointer", you are just getting yourself confused.
Write a function that should return two ints. You can't have two return values, so you write
void f (int* result1, int* result2)
{
*result1 = 1;
*result2 = 2;
}
Now write a function that should return two NSString*. That should make it obvious.

How do I enumerate on NSString?

How do I enumerate on NSString?
example of what I am trying to do:
enum eCat{
dog,
cat,
mouse,
bunny
};
#interface
#implementation
....
enum eCat Cate;
NSString *yoda = #"mouse";
Cate = [yoda intValue];
NSLog(#"Hello: %d",Cate);
wanting the result to be
Hello: 2
thanks
You have to create a mapping (string → enumeration) yourself. One possibility would be something like this (disclaimer: only brain-compiled):
#define CAT_(a, b) a##b
#define CAT(a, b) CAT_(a, b)
#define E(en) [NSNumber numberWithInt:en], CAT(#, #en),
NSDictionary *mapping = [NSDictionary dictionaryWithObjectsAndKeys:
// ...
E(mouse)
E(bunny)
nil];
NSNumber *result = [mapping objectForKey:#"mouse"];
if (!result) {
// ... oops
} else {
enum eCat cate = [result intValue];
}
There's no direct support of such an enumeration in Objective-C.
Instead, create an array of the strings and look for an entry:
static NSArray* enumeration=nil;
if(!enumeration){
enumeration=[[NSArray arrayWithObjects:#"AAA",#"BBB",#"CCC",nil] retain];
}
then use it later:
NSInteger i=[enumeration indexOfObject:#"BBB"];
/* i is now 1 */
It's unrelated to your question, but please don't start a variable name with a capital letter, like your Cate. That's against the convention of Objective-C.

NSArray of structures?

Trying to implement the following structure from "c" to use NSArray in objective-c:
In standard-c:
struct structDog{
char *name;
int age;
};
struct structLitter{
struct structDog puppy[10];
};
Then I use malloc to allocate space.
But since I am using NSArray.
But in Objective-c I am using NSArray... so ???
NSArray struct structDog *puppy; // <<---this doesn't work
thanks
Assuming that you are trying to do is get your struct into your NSArray you need to use NSValue. For instance you can do something like:
NSArray* myArray = [NSArray arrayWithObjects:[NSValue valueWithPointer: myDog],
[NSValue valueWithPointer: myPuppy],
nil];
structDog* dog = (structDog*)[[myArray objectAtIndex:0] pointerValue];

How can I add a boolean value to a NSDictionary?

Well, for integers I would use NSNumber. But YES and NO aren't objects, I guess. A.f.a.i.k. I can only add objects to an NSDictionary, right?
I couldn't find any wrapper class for booleans. Is there any?
You use NSNumber.
It has init... and number... methods that take booleans, just as it does integers and so on.
From the NSNumber class reference:
// Creates and returns an NSNumber object containing a
// given value, treating it as a BOOL.
+ (NSNumber *)numberWithBool:(BOOL)value
and:
// Returns an NSNumber object initialized to contain a
// given value, treated as a BOOL.
- (id)initWithBool:(BOOL)value
and:
// Returns the receiver’s value as a BOOL.
- (BOOL)boolValue
The new syntax since Apple LLVM Compiler 4.0
dictionary[#"key1"] = #(boolValue);
dictionary[#"key2"] = #YES;
The syntax converts BOOL to NSNumber, which is acceptable to NSDictionary.
If you are declaring it as a literal and you are using clang v3.1 or above, you should use #NO / #YES if you are declaring it as a literal. E.g.
NSMutableDictionary* foo = [#{ #"key": #NO } mutableCopy];
foo[#"bar"] = #YES;
For more info on that:
http://clang.llvm.org/docs/ObjectiveCLiterals.html
As jcampbell1 pointed out, now you can use literal syntax for NSNumbers:
NSDictionary *data = #{
// when you always pass same value
#"someKey" : #YES
// if you want to pass some boolean variable
#"anotherKey" : #(someVariable)
};
Try this:
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setObject:[NSNumber numberWithBool:TRUE] forKey:#"Pratik"];
[dic setObject:[NSNumber numberWithBool:FALSE] forKey:#"Sachin"];
if ([dic[#"Pratik"] boolValue])
{
NSLog(#"Boolean is TRUE for 'Pratik'");
}
else
{
NSLog(#"Boolean is FALSE for 'Pratik'");
}
if ([dic[#"Sachin"] boolValue])
{
NSLog(#"Boolean is TRUE for 'Sachin'");
}
else
{
NSLog(#"Boolean is FALSE for 'Sachin'");
}
The output will be as following:
Boolean is TRUE for 'Pratik'
Boolean is FALSE for 'Sachin'