views:

406

answers:

3

Hey,

I am trying to write a cocoa touch static library. To keep it simple I would prefer not to use private variables within my interface file. The code right now looks like this:

interface file (myView.h):

@interface myView: UIView {

NSTimer * myTimer;

}

@end

implementation file (myView.h)

@implementation myView

@end

This NSTimer pointer is just a private variable so I tried this: (not working)

interface file (myView.h):

@interface myView: UIView {

}

@end

implementation file (myView.h)

NSTimer * myTimer;

@implementation myView

@end

It seems to work however it turned out that the timer is now a static variable.

Am I doing sth wrong or is there no solution?

+1  A: 

You can't define instance variables in your implementation file.

A possible solution is to have a private structure containing the private variables and have one publicly declared private variable pointing to this private structure:

@interface MyView {
   void *privateData;
}

Implementation file:

typedef struct {
   NSTimer *myTimer;
}  PrivateData;


@implementation MyView()

@property (readonly) PrivateData *privateData;

@end


@implementation MyView

- (id) init {
   if (self = [super init]) {
       privateData = malloc(sizeof(PrivateData));

       self.privateData->myTimer = nil; // or something else
   } 

   return self;
}

-(PrivateData *) privateData {
    return (PrivateData *) self->privateData;
}

- (void) myMethod {
   NSTimer *timer = self.privateData->myTimer;
}

- (void) dealloc {
    // release stuff inside PrivateData
    free(privateData);
    [super dealloc];
}

@end

It's not beautiful, but it works. Maybe there are better solutions.

Philippe Leybaert
this is really ugly (+1) anyway
Ghommey
+1  A: 

Just a note; trying to hide iVar's for the sake of security is silly. Don't bother.

For simplicity's sake, though, it has value.

However, a couple of solutions:

(1) If targeting iPhone OS or 64 bit Cocoa, you can @synthesize the ivar:

Foo.h:

@interface Foo:NSObject
@property(readwrite, copy) NSString *publiclyReadwriteNoiVar;
@property(readonly, copy) NSString *publiclyReadonlyPrivatelyReadwriteNoiVar;
@end

Foo.m:

@interface Foo()
@property(readwrite, copy) NSString *privateProperty;
@end

@implementation Foo
@synthesize publiclyReadwriteNoiVar, publiclyReadonlyPrivatelyReadwriteNoiVar, privateProperty;
@end

(2) Use a private subclass kinda like class clusters:

Foo.h:

@interface Foo:NSObject
@end

Foo.m:

@interface RealFoo:Foo
{
    .... ivars here ....
}
@end
@implementation RealFoo
@end

@implementation Foo
+ (Foo *) convenienceMethodThatCreatesFoo
{
   .... realFoo = [[RealFoo alloc] init]; ....
   return realFoo;
}
@end
bbum
+1  A: 

Depending on the goal of your encapsulation, there's also the @private directive:

Access Modifiers

pzearfoss