views:

190

answers:

2

Members, scholars, code gurus. My background is far from any computer programming thus my question may seems basic and somewhat trivial to you. Nevertheless it seems that I can't put my head around it. I have googled and searched for the answer, just to get myself confused even more. With that, I would kindly ask for a simple explanation suitable for a non technical person such as myself and for other alike arriving to this thread.

I have left a comment with the text "Here is the issue" below, referring to my question.

//  character.h
#import <Foundation/Foundation.h>

@interface character : NSObject {
    NSString *name;
    int hitPoints;
    int armorClass;
}

@property (nonatomic,retain) NSString *name;
@property int hitPoints,armorClass;

-(void)giveCharacterInfo;

@end


//  character.m
#import "character.h"


@implementation character
@synthesize name,hitPoints,armorClass;

-(void)giveCharacterInfo{
    NSLog(@"name:%@ HP:%i AC:%i",name,hitPoints,armorClass);
}
@end



//  ClassAtLastViewController.h
#import <UIKit/UIKit.h>

@interface ClassAtLastViewController : UIViewController {

}

-(void)callAgain;

@end



//  ClassAtLastViewController.m
#import "ClassAtLastViewController.h"
#import "character.h"

@implementation ClassAtLastViewController


- (void)viewDidLoad {
    //[super viewDidLoad];
    character *player = [[character alloc]init];
    player.name = @"Minsc";
    player.hitPoints = 140;
    player.armorClass = 10;
    [player giveCharacterInfo];
    [player release];
        // Up until here, All peachy!
    [self performSelector:@selector(callAgain) withObject:nil afterDelay:2.0];
}

-(void)callAgain{
    // Here is the issue, I assume that since I init the player again I loss everything
    // Q1. I loss all the data I set above, where is it than? 
    // Q2. What is the proper way to implement this

    character *player = [[character alloc]init];
    [player giveCharacterInfo];
}

Many thanks in advance, Kindly remember that my background is more related to Salmons breeding than to computer code, try and lower your answer to my level if it's all the same to you.

+4  A: 

I loss all the data I set above, where is it than?

It's been freed (released). Notice:

character *player = [[character alloc]init];    // You create the character here...
// And then you initialize it...
// Then later...
[player release];                               // You release it.

Even if you didn't release it, you still wouldn't be able to access it from callAgain, because you declare player in viewDidLoad. If you want it available to all methods in instances of ClassAtLastViewController, you should make it an instance variable.

What is the proper way to implement this

I don't know the specifics of your usage, but I imagine you want something like this:

@interface ClassAtLastViewController : UIViewController {
    character *player;    // Make player an instance variable
}

-(void)callAgain;

@end

@implementation ClassAtLastViewController


- (void)viewDidLoad {
    //[super viewDidLoad];
    player = [[character alloc]init];    // Initialize the instance variable
    player.name = @"Minsc";
    player.hitPoints = 140;
    player.armorClass = 10;
    [player giveCharacterInfo];
    [self performSelector:@selector(callAgain) withObject:nil afterDelay:2.0];
}

-(void)callAgain{
    [player giveCharacterInfo];
}
mipadi
Thank you kindly, I was using this method intuitively but got distracted by some errors I got.( error: expected specifier-qualifier-list before 'character')Following your answer I have managed to make it work by adding "#import "character.h" to the top of the ClassAtLastController.hMany thanks for explaining this thus pointing me into the right way, highly appreciated.
ShiShi
A: 

When you init the character in your callAgain function, you are actually creating a second instance of character. Even though the character created in callAgain has the same name as the character you created in viewDidLoad, it is a completely separate variable. The character you init in viewDidLoad only exists in the scope of the viewDidLoad function.

Also, when you call [player release] in viewDidLoad, you are removing that character instance from memory.

I think what you want to do is to create an instance variable that can be used throughout your class:

//  ClassAtLastViewController.h
#import <UIKit/UIKit.h>

@interface ClassAtLastViewController : UIViewController {
    character *player;
}

-(void)callAgain;

@end



//  ClassAtLastViewController.m
#import "ClassAtLastViewController.h"
#import "character.h"

@implementation ClassAtLastViewController


- (void)viewDidLoad {
    //[super viewDidLoad];
    player = [[character alloc]init];
    player.name = @"Minsc";
    player.hitPoints = 140;
    player.armorClass = 10;
    [player giveCharacterInfo];

    [self performSelector:@selector(callAgain) withObject:nil afterDelay:2.0];
}

-(void)callAgain{
    // Here is the issue, I assume that since I init the player again I loss everything
    // Q1. I loss all the data I set above, where is it than? 
    // Q2. What is the proper way to implement this

    [player giveCharacterInfo];
}
dl
Thank you, Excellent answer.
ShiShi