PDA

View Full Version : allocation and retention of objects?




jerrywickey
May 4, 2009, 10:38 PM
The instance variables of an object work to maintain the state of the object. As the application journeys through multiple touch events, the state of some objects must be retained in ways which repeatedly allocating and releasing objects can not accomplish.

OOP must provide for this in some way other than by the use of declaring class variables instead of instance variables. I am an old assembly language programmer from the Z80 days. I have been playing with the Objective C platform for the IPhone and can not find another way to maintain the object "oporate"'s state variables through multiple "testViewController" event methods without declaring "oporate"'s methods as class instead of instance.

Below is the simple test code I used to demonstrate this. Perhaps, my old brain just missed something obvious.

In the simple test code below, the "oporate" class variable "remember" maintains its value through multiple "testViewController" methods. The compile succeeds and the simulation runs with out fault, but the compiler grunts "warning: instance variable -remember- accessed in class method"

Is there another way to declare this variable? one such that it retains its value. Perhaps some use of the retain method, but in what way?

How does the adroit OOPs programmer maintain the values of the state variables of an object that lives the life of the application?

Jerry

testViewController.h

/*
*testViewController.h
*/

#import <UIKit/UIKit.h>
#import "oporate.h"

@interface testViewController : UIViewController {
IBOutlet UILabel *label; }

-(IBAction) button1: (id) sender;
-(IBAction) button2: (id) sender;

@property (nonatomic, retain) UILabel *label;

@end
testViewController.m
/*
*testViewController.m
*/

#import "testViewController.h"
#import "oporate.h"

@implementation testViewController

@synthesize label;

-(IBAction) button1: (id) sender {
[oporate setrem];
label.text = [NSString stringWithFormat: @"%i", [oporate addone]]; }

-(IBAction) button2: (id) sender {
[oporate setrem2];
label.text = [NSString stringWithFormat: @"%i", [oporate addten]]; }

-(void) viewDidLoad {
[oporate start];
[super viewDidLoad]; }

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

@end

oporate.h
/*
*oporate.h
*/

#import <Foundation/Foundation.h>

@interface oporate : NSObject {
int remember; }

+(void) start;
+(void) addone;
+(void) addten;
+(int) recallrem;

@end

oporate.m
/*
*oporate.m
*/

#import "oporate.h"

@implementation oporate

+(void) start {
remember = 1; }

+(void) addone {
remember = remember + 1; }

+(void) addten {
remember = remember + 10; }

+(int) recallrem {
return remember; }

@end



Holy rats!!

Is getting rid of the compiler hicup as simple as?
/*
*oporate.h
*/

#import <Foundation/Foundation.h>

int remember;

@interface oporate : NSObject { }

....
Instead of
/*
*oporate.h
*/

#import <Foundation/Foundation.h>

@interface oporate : NSObject {
int remember; }

....

But this still leaves the question: Must state values which must be maintained through multiple methods be declared in classes instead of instances of classes?

Jerry



kainjow
May 4, 2009, 11:24 PM
Yes. Use instance variables if you want them to last for the life of the class. If you just need a variable temporarily, declare it in the method locally.

Edit: to be clearer... if you're using a class with only class methods, then yes you need to declare a variable outside of the class. But this is rare. It's better to use singletons in these cases.

jerrywickey
May 5, 2009, 12:08 AM
Thank you very much for the confirmation.

To be sure. I need a large string and a focus location on one character in that string which many other classes will reference. The string won't change, but the focus will and the focus needs to be available from multiple methods of several classes.

I should make it a class by itself and use all class methods for the getter and setter of the focus? Is that correct. Actually the getter won't get the focus but usually deliver the characters from the string according to the focus.

Isn't that really what a singleton is anyway? I am not sure, is there may be a class provided for a singleton?

Jerry

kainjow
May 5, 2009, 12:26 AM
A singleton returns an instance of a shared object.

So for example:

// .h
@interface Thing : NSObject {
NSString *str;
int loc;
}

+ (Thing *)shared;

@property (readwrite, retain) NSString *str;
@property (readwrite) int loc;

@end

// .m
@implementation Thing

@synthesize str, loc;

+ (Thing *)shared {
static Thing *shared = nil;
if (!shared) shared = [[Thing alloc] init];
return shared;
}

- (id)init {
self = [super init];
self.str = @"My string";
return self;
}

@end


This is how I prefer to setup singletons, so I don't have to put variables outside of the class. The "static" here is crucial.

Then you could use it like this in all of your classes:

[Thing shared].loc = 2;

PhoneyDeveloper
May 5, 2009, 08:26 AM
@Jerry, your class is a kind of singleton. I often design singleton classes like this, with all class methods, rather than the way that Apple seems to prefer it, and like kainjow has shown.

Objective-C, unlike C++ for example, has no concept of a class variable. This means you need to use a plain global, like you have done. BTW, you've placed your remember variable in the wrong place. It doesn't go inside the class declaration and it doesn't go in the header file. It goes in the .m file and is declared static:

static int remember;

This makes it a file scope static, which is the way that one does class variables in Obj-C.

jerrywickey
May 5, 2009, 05:04 PM
Thank you very much.

This is exactly what I was asking.

Jerry

And, Kain,

I love that " [Thing shared].loc = 2; " so elegant.