Not Able to Get Properties

Discussion in 'Mac Programming' started by parkov, Aug 30, 2008.

  1. macrumors newbie

    Joined:
    Aug 29, 2005
    #1
    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.
     
  2. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    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.
     
  3. thread starter macrumors newbie

    Joined:
    Aug 29, 2005
    #3
    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.
     
  4. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    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
     
  5. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #5
    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.
     
  6. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #6
    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;
    }
    
     
  7. thread starter macrumors newbie

    Joined:
    Aug 29, 2005
    #7
    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?
     

Share This Page