Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

parkov

macrumors newbie
Original poster
Aug 29, 2005
24
19
Could someone help me out with this basic thing? I'm not able to set or get properties of a subclassed object.

Header:
Code:
#import <UIKit/UIKit.h>

@interface Car : NSObject {
	NSNumber *position;
}

- (NSNumber *)position;
- (void)setPosition:(NSNumber *)newPosition;


@end

Implementation:

Code:
#import "Car.h"

@implementation Car


- (id)init {	
	[self setPosition:[NSNumber numberWithInt:42]];		
	return self;
}

- (NSNumber *)position{
	return [[position retain] autorelease];		
}

- (void)setPosition:(NSNumber *)newPosition{
	if (position != newPosition){
		[position release];
		position = [newPosition copy];
	}
}

- (void)dealloc {	
	[super dealloc];
}

@end

After creating Car carA, this code puts a (null) in Console:

Code:
NSLog(@"Position set to %@", [carA position]);

It seems I'm not setting the property correctly but I don't see where I'm going wrong. I've tried setting it in other places besides init as well.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
I'm not at my computer, but:
Position is uninitialized when you call setPosition from init

You cannot compare NSNumber *s with ==. This will compare the pointers. This will work as a fluke with values up to about 12 as the runtime caches copies of NSNumber to this point. Use compare instead.

Once you change these things, add some debug to your methods, printing the value and pointer with %p of location and see when it changes.

-Lee

PS I don't know how this works, but init is not in your header so when your class is used the superclass init, in this case NSObject's, may be used. Debug in init would tell you this.
 

parkov

macrumors newbie
Original poster
Aug 29, 2005
24
19
Thanks for the tips. I've changed the setPosition method in the implementation file as:

Code:
- (void)setPosition:(NSNumber *)newPosition{	
	
	NSLog(@"newposition %@ %p", newPosition, newPosition);
	
	if ([position isEqualTo:newPosition]){
	}else{
		[position release];
		position = [newPosition copy];
	}
}

I tried calling the get in another class' viewDidLoad.

Code:
	[carA setPosition:[NSNumber numberWithInt:42]];
	NSLog(@"viewdidload %@ %p", [carA position], [carA position]);

I notice that the NSLog in viewDidLoad prints (null) but the NSLog in setPosition does not print. It seems that setPosition is not being called at all.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
well that's no good. So carA has been alloc'd, init'd and is not nil when you start passing messages to it? If it were nil this behavior would make some sense.

Also, does NSNumber inherit isEqualTo, and are you sure it works? I only saw compare and isEqualToNumber.

-Lee
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
You cannot compare NSNumber *s with ==. This will compare the pointers. This will work as a fluke with values up to about 12 as the runtime caches copies of NSNumber to this point. Use compare instead.

That is not what this comparison is about. It is supposed to check whether you called setPosition, passing in exactly the same object that is already stored in the object. In that case, doing anything would be unnecessary and pointless. This is a very simple and quick check that avoids calling the copy method, which might be rather expensive. Using the compare method would be much more expensive.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,566
Just wondering: Do you have any particular reason for using an NSNumber* instead of for example double for the position? Using plain double, the code is much simpler (I added the missing call to [super init]), it will run faster and the objects take much less space:

Code:
- (id)init {	
	if (self = [super init])
		self->position = 42;		
	return self;
}

- (double)position{
	return self->position;		
}

- (void)setPosition:(double) newPosition{
	self->position = newPosition;
}
 

parkov

macrumors newbie
Original poster
Aug 29, 2005
24
19
Thanks for your help guys. It turned out that my alloc init code was messed up which should have been the obvious place to look.

The reason I am using NSNumber is because I plan to call some NSArray methods down the line. Does it make a big performance difference to use ints or doubles and then stuff them into NSNumbers when working with NSArray?
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.