0

I am a little confused about how I "set" and "get" the instance variables for an object that is contained within another. As you can see from the code below I first create a RocketBody which includes a SolidRocketMotor object. I am creating the SolidRocketMotor in RocketBody init and deallocating it in RocketBody dealloc.

My question is how would I go about setting / getting the engine (SolidRocketMotor) instance variables from within main (e.g. setting engCase)?

int main (int argc, const char * argv[]) {
    RocketBody *ares_1x;

    ares_1x = [[RocketBody alloc] init];
    [ares_1x setFuel: [NSNumber numberWithInt:50000]];
    [ares_1x setWeight:[NSNumber numberWithFloat:1.8]];
    // How to set engCase to "Standard" here?
...

.

@interface SolidRocketMotor : NSObject
{
    NSString *engCase;        
    NSString *engPropellant;  
    NSNumber *engIgniter;    
    NSString *engNozzle;      
}
@property(copy) NSString *engCase;
@property(copy) NSString *engPropellant;
@property(copy) NSNumber *engIgniter;
@property(copy) NSString *engNozzle;
@end

@interface RocketBody : NSObject
{
    NSNumber *fuel;
    NSNumber *weight;
    BOOL holdDownBolt_01;
    BOOL holdDownBolt_02;
    BOOL holdDownBolt_03;
    BOOL holdDownBolt_04;
    SolidRocketMotor *engine;
}
@property(copy) NSNumber *fuel;
@property(copy) NSNumber *weight;
@property BOOL holdDownBolt_01;
@property BOOL holdDownBolt_02;
@property BOOL holdDownBolt_03;
@property BOOL holdDownBolt_04;
@end

// ------------------------------------------------------------------- **
// IMPLEMENTATION
// ------------------------------------------------------------------- **

@implementation SolidRocketMotor
- (id) init {
    self = [super init];
    if (self) NSLog(@"_init: %@", NSStringFromClass([self class]));
    return self;
}

@synthesize engCase;
@synthesize engPropellant;
@synthesize engIgniter;
@synthesize engNozzle;

- (void) dealloc {
    NSLog(@"_deal: %@", NSStringFromClass([self class]));
    [super dealloc];
}
@end

// ------------------------------------------------------------------- **

@implementation RocketBody
- (id) init {
    self = [super init];
    if (self) {
        engine = [[SolidRocketMotor alloc] init];
        NSLog(@"_init: %@", NSStringFromClass([self class]));
    }
    return self;
}

@synthesize fuel;
@synthesize weight;
@synthesize holdDownBolt_01;
@synthesize holdDownBolt_02;
@synthesize holdDownBolt_03;
@synthesize holdDownBolt_04;

- (void) dealloc {
    NSLog(@"_deal: %@", NSStringFromClass([self class]));
    [engine release], engine = nil;
    [super dealloc];
}
@end

many thanks

gary

2 Answers 2

2

supposing you have something like and that you declare a property setting for SolidRocketMotor *engine:

RocketBody *rb = [[RocketBody alloc] init];

Then you would do this:

SolidRocketMotor *srm = [[SolidRocketMotor alloc] init];

rb.engine = srm;

and

rb.engine.engCase = whatever;
Sign up to request clarification or add additional context in comments.

4 Comments

Maybe I just have the logic wrong, the problem right now is that the engine [SolidRocketMotor] is assigned/allocated in the init, so I don't (as far as I can see) have access to engine from main(); Maybe allocating the [SolidRocketMotor] within the [RocketBody init] is not the right thing to be doing?
This only works if engine is a property in RocketBody, which it isn't in the OP's code.
I apologize. I indeed overlooked your first sentence. And so did the OP apparently.
I voted ennuikiller up as I think his answer was helpful, but just not as clearly stated as yours @Ole which I marked as accepted, thank you both.
1

You need to provide an accessor for engine in your RocketBody class. Like this:

@interface RocketBody : NSObject
{
    // ...
    SolidRocketMotor *engine;
}
// ...
@property(retain) SolidRocketMotor *engine;
@end

@implementation RocketBody
// ...
@synthesize engine;
// ...
@end

With this, external code can access the engine property:

// Obj-C 2.0 Property style:
ares_1x.engine.engCase = @"Standard";

// or setter/getter method style:
[[ares_1x engine] setEngCase:@"Standard"];

3 Comments

Ole, can I ask you where you would alloc/init & dealloc the engine? I only ask as currently I am doing this is main() and then assigning that object with [ares_1x setEngine:aresEngine]; I am a little worried that this allows direct access to the engine, without going the ares_1x route that you so helpfully mention?
I think I got it, I went back to allocating the engine in the [RocketBody init] and deallocating it in the [RocketBody dealloc] which feels better as its hidden away in the rocket once again ...
Yes, that's right, the rest of your code should remain as it was.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.