5

Have spent several hours on this and am sure I'm missing something completely obvious. I'm new to cocoa/objective c and rusty with pointers / objects, and thus would greatly appreciate someone (kindly!) pointing out where I'm going wrong.

Here is my code:

.h file:

@property (assign) NSInteger *freeTrialCounter;

.m file

NSInteger a = 2;
self.freeTrialCounter = &(a);   

NSLog(@"Free Trial Counter: %d", *self.freeTrialCounter);

int b = *self.freeTrialCounter;
NSLog(@"B: %d", b);

here is the output: Free Trial Counter: 2 B: 1606411536

What am I missing here? Why isn't "B" equal to "2"?

dandan78
  • 13,328
  • 13
  • 64
  • 78
  • 1
    What's the point of creating a pointer to an `int` as a property? Merely for experimental purposes or what? This is not something that seems to have any common real-world application – dandan78 May 16 '14 at 18:09
  • 1
    Tried your code, B returns 2 for me. Only possible issue I thought of, is that NSInteger is actually a long and not an int. Meaning it is 64bit and not 32bit. You have possible data loss when doing the explicit conversion with 'b' – Yarneo May 16 '14 at 18:12
  • dandan78 & Yameo: see my response below to Caleb's help... was following the advice of XCode "&(a)" and it led me astray. (Being new to this language, I assumed I ought to listen to the IDE's advice... I know better now!) Thanks for your time and assistance on this. – user3643251 May 16 '14 at 19:07

1 Answers1

3

The root of the problem is that int and NSInteger can be different sizes. So, you're assigning a pointer to an NSInteger to a property of type NSInteger*, which is okay (but unusual). However, you're dereferencing that value as an int, which happens not to be the same size.

However, I think that you may also be confused about how you need to declare a property to hold an NSInteger. NSInteger is just a simple integer type, not an object, so there's no need to use a pointer to refer to it. This is doubly true since you seem to be declaring the NSInteger whose address you're taking on the stack, so the pointer will be invalid as soon as the method where you do the assignment ends.

You'll be much better off using a plain old NSInteger property and not trying to use a pointer here. Do this instead:

@property (assign) NSInteger freeTrialCounter;
//...
NSInteger a = 2;
self.freeTrialCounter = a;   

NSLog(@"Free Trial Counter: %ld", self.freeTrialCounter);

NSInteger b = self.freeTrialCounter;
NSLog(@"B: %ld", b);

Note that I've also changed the type of b to NSInteger to match the property type. Since they're not necessarily the same size, mixing the two can (as you've seen) cause problems. Likewise, I've changed the format specifier from %d to %ld to match the 64-bit size of NSInteger.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • 1
    If he wanted to use pointers, for whatever reason, thats his choice. You aren't really helping him find his problem. Rather just giving an alternative. – Yarneo May 16 '14 at 18:15
  • @Yarneo You make a fair point and I'll edit to address the actual problem. OTOH, there's really not much point to storing a pointer to an integer as a property, though, so I tend to think that the OP simply made a mistake. You *must* use pointers for objects, but `NSInteger` isn't an object type. – Caleb May 16 '14 at 18:19
  • Thanks for the help Caleb, et. al... When I code the self.freeTrialCounter=a; XCode gives me the following "yellow warning": "Incompatible integer to pointer conversion assigning to 'NSInteger *' (aka 'long *') from 'NSInteger' (aka 'long'); take the address with &" and recommends the change &(a). Being new to cocoa, I simply assumed that XCode knew what it was doing, and accepted the change... which is obviously not always accurate! Thanks very much for your help. Working brilliantly now! – user3643251 May 16 '14 at 19:06