Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objective-c union "->" vs "."

Tags:

c

objective-c

let me start by saying i am pretty new to the whole struct and union thing. i have done my homework before posting this and honestly trying to get legitimate clarification. if this is the wrong way to this please let me know. first off, i am attempted to create a union because i am combining different data types. my only real problem / question is the dot operator vs the ->. i can get what i want working using the

->

but not the

.

im just curious as to why? iv read a bunch of posts on stack that show examples or "answers" using the ".", but no luck in the real world. i have played with "typedef" like...

typedef union _myUnion
{
     int intValue;
     bool boolValue;
}myUnion;

but that doesn't seam to make a difference. if anyone explain what im doing wrong it would be greatly appreciated. here is a quick sample of what i am trying to do. for the sake of simplicity, i will just post some struct/union syntax and wont add any of the sub-classing code since that's not an issue.

example.h

#import "<Foundation/Foundation.h"

union myUnion
{
   int intValue;
   bool boolValue;
};

@interface MyClass : NSObject
{
    union myUnion *someProperty;
}

@property (nonatomic, assign) union myUnion *someProperty;

-(void)doSomething;

@end

example.m

#import "MyClass.h"

@implementation MyClass

@synthesize someProperty = _someProperty;

- (id)init
{
//Some init method...
}

- (void)doSomething
{
    NSLog(@"I Did Something...");
}

@end

so now in my other class this works...

MyClass *newObject = [MyClass alloc] init];
newObject.someProperty->intValue = 6;

but this doesn't...

MyClass *newObject = [MyClass alloc] init];
newObject.someProperty.intValue = 6;

at this point in time i'm more interested in learning why that latter doesn't work? what's interesting is if i take off the pointer in the .h file for the property.

@interface MyClass : NSObject
    {
        union myUnion someProperty;
    }

@property (nonatomic, assign) union myUnion someProperty;

the "." works instead of the "->", but now its not assignable.

as a side note, if i change the bool to an int and make it a struct the same thing happens. unfortunately i became proficient at objective-c first and am slowly picking up strict c as i go. so my understanding of c is a tad weak, but that's the beauty of obc, i get to learn two languages for the price of one! if you don't count open-gl.

i would ask, if someone could post a working example of code and i can then figure out what i did wrong, or explain thoroughly what it is i am doing wrong and some of the fundamental concepts i missed. from there i can figure out how to write my own working code. i don't need both, and don't expect a hand out but would like to learn so i can solve my own problems and not just patch buggy code without understanding how or why it works.

like image 211
DoS Avatar asked Apr 26 '12 00:04

DoS


2 Answers

The a->b operator is shorthand for (*a).b - it's like using the . but doing a dereference first. It's appropriate when a is a pointer.

Since in your original example someProperty is a pointer to a union, you'll need to dereference that pointer first. This means you'll need to either use:

(*newObject.someProperty).intValue // confusing!

Or

newObject.someProperty->intValue // much better

to access it.

Of course, once you've changed someProperty to be a union instead of a pointer to a union, you can use the . instead. So:

  • a->b: Accesses a struct/union member on a pointer
  • a.b: Accesses a struct/union member on a raw struct/union
like image 99
Timothy Jones Avatar answered Oct 24 '22 20:10

Timothy Jones


In this case, it's quite probable that you want the union as a value -- not a pointer to an external memory location:

@interface MyClass : NSObject
{
    union myUnion someProperty; // << no '*'
}

@end

then you use the period for member access:

someProperty.intValue = 6;

and if it were a pointer:

someProperty->intValue = 6;

However, there's another issue. You have two (primary) options to use the union as a property. Value or pointer. This is commonly handled by value, especially when all fields refer to memory local to the structure/union, and when the field id not large. In this case, you would often return and set by value. This means that your program would be written as follows:

@interface MyClass : NSObject
{
    union myUnion someProperty;
}

@property (nonatomic, assign) union myUnion someProperty; // << by value

@end

then the client may access and set it by value, like so:

union myUnion p = obj.someProperty;
++p.intValue;
obj.someProperty = p;

and that's how it's often accomplished with small structures which don't refer to shared resources.

Of course, you will not need a copy when your instance has direct access to it, should you choose to access the field directly:

- (void)doSomething
{
  ++someProperty.intValue;
}

if this becomes complex, it's likely a good idea to abstract the data behind methods, and leave accessing and mutation to the instance of MyClass which holds the union.

like image 29
justin Avatar answered Oct 24 '22 20:10

justin