0

I'm tearing my hair out over this.. I've no idea what's going wrong.

I've created a very simple Coordinates2D class to store two NSInteger values, as well as a string representation for use with NSLog. I'm running this code in the iOS 4.3 iPad simulator bundled with the latest version of xCode.

For some reason the integer values passed to the initX:Y: constructor gets lost. The code below provides Coordinates2D and some code to print an arbitrary float value in its original form, cast as an int, cast as an NSInteger, and then inside the Coordinates2D object.

You should see, as I do, that the value gets lost inside the Coordinates2D constructor; the 'coords.x' argument in NSLog is printed as a random, large integer indicating its value has been lost in memory.

Can anyone help me see why this happens? I can't see what I'm doing wrong.

Many thanks!

Coordinates2D.h

#import <Foundation/Foundation.h>
@interface Coordinates2D : NSObject {
    NSInteger x,y;
    NSString *asString;
}
@property (nonatomic) NSInteger x,y;
@property (nonatomic, retain) NSString *asString;
-(void)updateStringRepresentation;
-(id)initX:(NSInteger)x Y:(NSInteger)y;
@end

Coordinates2D.m

#import "Coordinates2D.h"
@implementation Coordinates2D
@synthesize x,y,asString;

-(id)initX:(NSInteger)x_ Y:(NSInteger)y_ {
    NSLog(@"coords: %i, %i",x_,y_);
    if ((self = [super init])) {
        self.x = x_;
        self.y = y_;
        NSLog(@"Coordinates stored %i as %i",x_,self.x);
        [self updateStringRepresentation];
    }
    return self;
}
/*
-(void)setX:(NSInteger)newX {
    x = newX;
    [self updateStringRepresentation];
}

-(void)setY:(NSInteger)newY {
    y = newY;
    [self updateStringRepresentation];
}
*/
-(void)updateStringRepresentation {
    self.asString = [NSString stringWithFormat:@"%i,%i",x,y];
}

-(void)dealloc {
    [asString release];
    [super dealloc];
}
@end

Example of problem:

Coordinates2D *coords = [[Coordinates2D alloc] initX:(NSInteger)(202.566223/200.00) Y:0.0f];
NSLog(@"202.566223/200.00 = %f, as int:%i, as NSInteger:%i, as Coordinates2D:%i",
      202.566223/200.00, (int)(202.566223/200.00), (NSInteger)(202.566223/200.00), coords.x);
KomodoDave
  • 7,239
  • 10
  • 60
  • 92
  • For what it’s worth, your code runs fine as a Mac application — as it should, since the conversion of 1.012831 to `NSInteger` is a valid/defined conversion. –  Apr 17 '11 at 00:08
  • I’d suggest you override the `-description` method to return `asString`, e.g. `- (NSString *)description { return self.asString; }` –  Apr 17 '11 at 00:09
  • Thanks for the 'description' tip. I wonder if I've unrooted an iOS bug, I don't see a problem with the code I've written. I'll wait and see if someone can identify an issue, I can't see one though :( – KomodoDave Apr 17 '11 at 00:18
  • The best advice I can give is to set a breakpoint for just before the `Coordinates2D *coords = [[Coordinates2D alloc] initX:(NSInteger)(202.566223/200.00) Y:0.0f];` line, and then step through it in the debugger printing the relevant values at every step until you find out where it's going wrong. – Anomie Apr 17 '11 at 00:22
  • Does it happen to **every** `Coordinates2D` object you create? Does changing the `float` arguments always reproduce the errors? –  Apr 17 '11 at 00:23
  • I've already tried breakpoints sadly - the NSInteger value is maintained until a breakpoint on the Coordinates2D construction line, then as soon as you step into the Coordinates2D constructor the value is lost. The only way I found to overcome the problem was to have a no-arguments init for Coordinates2D and to set x, y once it has been constructed. – KomodoDave Apr 17 '11 at 06:45

2 Answers2

0

I read awhile ago that you should never use the property accessor in init methods.

Black Frog
  • 11,595
  • 1
  • 35
  • 66
  • While I agree that using accessor methods in `-init` methods can have undesired side effects — and Apple does discourage developers from using them in `-init` and `-dealloc` —, this isn’t an answer to the original question. It’s a good comment, though. –  Apr 17 '11 at 01:11
  • Particularly if you're overriding the accessor methods. – Terry Wilcox Apr 17 '11 at 01:11
-2

I think you want to change:

@property (nonatomic) NSInteger x,y;

to:

@property (nonatomic, assign) NSInteger x,y;

That should fix the error, as it runs fine when I put it in an xcode project.

msgambel
  • 7,320
  • 4
  • 46
  • 62