I am new to ObjectiveC and I have following inheritance.
#interface CGameEntity : NSObject {
b2Body *entityBody;
}
#property(nonatomic,retain) CCSprite *entitySprite;
-(id)initEntity:(CCNode*)parentNode :(b2World*)world;
#end
implementation :
#implementation CGameEntity
#synthesize entitySprite=entitySprite;
.
.
.
#end
And extended class is as follows :
#interface CPlanet : CGameEntity {
}
#end
implementation is as follows:
#implementation CPlanet
-(id)initEntity:(CCNode*)parentNode :(b2World*)world
{
if((self = [super init]))
{
//cannot access "entitySprite" ????
entitySprite=[CCSprite spriteWithFile:#"planet.png"];
}
return self;
}
#end
In the extended class I cannot access the property "entitySprite".
How can I access properties of the base class ?
Thank you
First of all, replace ...
#synthesize entitySprite=entitySprite;
By ...
#synthesize entitySprite;
Then, replace this line ...
entitySprite=[CCSprite spriteWithFile:#"planet.png"];
By this ...
self.entitySprite = [CCSprite spriteWithFile:#"planet.png"];
This will work =)!
Related
I have a class which internally uses an ivar. I don't want to expose the ivar in the public interface of the class (the header) but I declare and use it in the implementation file, like so:
//--------SomeClass.h--------------
#interface SomeClass : NSObject
#end
//--------SomeClass.m--------------
#implementation SomeClass ()
{
#protected
NSMutableDictionary *_privateData;
}
#implementation SomeClass
// ...
#end
Then in a subclass of SomeClass, I try to access _privateData:
//--------SomeSubClass.m--------------
#implementation SomeSubClass
// ...
- (void)someMethod {
NSLog(#"%#", _privateData); // NOPE
NSLog(#"%#", self->_privateData); // NOPE
NSLog(#"%#", super->_privateData); // NOPE
}
// ...
#end
But I can't. Is there a way to do this?
In order to achieve the desired behavior, you should create a subclass header file which declares all of your protected data and #import it in your subclass' .m file.
MammalSubclass.h:
#interface Mammal () {
#protected
NSMutableDictionary *_privateData;
}
//...
#end
Human.m:
#import "Human.h"
#import "MammalSubclass.h"
#implementation Human //subclasses Mammal
- (void)someMethod {
NSLog(#"%#", _privateData);
}
//...
#end
Example:
#class MyRootObject;
#interface MyObject : MyRootObject
#end
Getting form XCode:
Class MyObject defined without specifying a base class.
MyRootObject class is:
#interface MyRootObject : NSObject
- (id)init;
#end
#implementation MyRootObject
- (id)init
{
self = [super init];
if(self){
// some code here
}
return self;
}
#end
You can't inherit from a forward-declared class. You need to #include the appropriate header instead.
//MainClass.m
#interface InnerClass : NSObject{
}
#end
#implementation InnerClass
-(void)run{
while(isActive){//want to access this variable which defined in MainClass
//do something
}
}
#end
#interface MainClass : NSObject{
BOOL isActive;
}
#end
#implementation MainClass
#end
I have MainClass and it has an inner class (InnerClass). I want to access the boolean type variable (isActive) defined in MainClass class from the inner class. What I am trying to do is that the inner class will run on a separate thread and will keep checking the isActive variable on the main class and if isActive is false then it will stop running the new thread.. Thanks in advance...
Objective-C doesn't have inner classes. Consider making isActive a property of MainClass, give InnerClass a pointer to an instance of MainClass, and let InnerClass simply access the property.
Objective-C doesn't have inner classes as a language construct, however you can do all sorts of tricky things like hiding both the interface and implementation of the "innerclass" in the .m file of the MainClass and having a hidden factory method (not in the interface) on the MainClass that creates the 'innerclass' with a bool* property assigned to &isActive of the main class.
MainClass.h
#interface MainClass : NSObject{
BOOL isActive;
}
#end
MainClass.m
#interface InnerClass : NSObject{
BOOL* isActive;
}
-(id)initWithActive:(BOOL*)isAct){
if (self = [super init]) {
isActive = isAct;
}
return self;
}
#end
#implementation InnerClass
-(void)run{
while(*isActive){//want to access this variable which defined in MainClass
//do something
}
}
#end
#implementation MainClass
//Can use [self newInnerClass] to create a new instance of the innerclass
-(id)newInnerClass{
return [[[InnerClass alloc] initWithActive:&isActive] autorelease];
}
#end
I have CCAction *action1; in classA. I need to use that action in classB.
I need to run action1 along with other actions in classB. How can I do that ?
I did in the following way but not working.
warning: 'CCAction' may not respond to '+actionWithAction:'
Here are my classA and classB.
#interface classA : CCLayer {
CCAction *ActionScale;
}
#property (nonatomic, retain)CCAction *ActionScale;
#end
#import "classA.h"
#implementation classA
#synthesize ActionScale;
-(id)init
{
if( (self = [super init]) )
{
...
ActionScale = [CCScaleBy actionWithDuration:1.0f scale:2.0];
}
return self;
}
//classB
#class classA;
#interface classB : CCLayer {
CCSprite *sprite1;
classA *object1;
}
#property(nonatomic, retain)classA *object1;
#end
#import "classB.h"
#import "classA.h"
#implementation classB
#synthesize object1;
-(id)init
{
if( (self = [super init]) )
{
...
...
id eggAction3 = [CCAction actionWithAction:object1.ActionScale];
}return self;
}
What method should we use to call the CCAction of one class in to other class ?
Thank you.
I'm not sure exactly what you are trying to do, but couldn't you just say, in classB:
id eggAction3 = object1.ActionScale;
That would give you a reference to the action in the other object, since you've set it up as a property in the other class.
It might help to describe what you're trying to achieve with this setup.
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?
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.
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
Depending on the goal of your encapsulation, there's also the #private directive:
Access Modifiers