Ok! This is the main Scene were I initialize the game, and in the ParallaxBgTestLayer there is a class that is added as child of self called DigBackground which has a property which I want to set from the other layer gameplayLayer.
So basically I want to access a child of a child in another class from my gameplay layer. What is the preferred way of doing this? Is it even possible to access child of other classes with tags?
-(id) init
{
self = [super init];
if (self)
{
ParallaxBgTestLayer *bgLayer = [ParallaxBgTestLayer node];
[self addChild:bgLayer z:kParallaxBackgroundLayer];
DigGameplayLayer *gameplayLayer = [DigGameplayLayer node];
[self addChild:gameplayLayer z:kGameplayLayer];
}
return self;
You can do it in very simple way:
#class ParallaxBgTestLayer;
#class DigGameplayLayer;
#interface MainClass
{
ParallaxBgTestLayer *bgTestLayer;
DigGameplayLayer *gameplayLayer;
}
#property(monatomic, assign) ParallaxBgTestLayer bgTestLayer;
#property(monatomic, assign) DigGameplayLayer *gameplayLayer;
#end
#implementation MainClass
-(id) init
{
self = [super init];
if (self)
{
self.bgLayer = [ParallaxBgTestLayer initWithParent:self];
[self addChild:self.bgLayer z:kParallaxBackgroundLayer];
self.gameplayLayer = [DigGameplayLayer initWithParent:self];
[self addChild:self.gameplayLayer z:kGameplayLayer];
}
return self;
}
#end
#interface ParallaxBgTestLayer
{
CCNode *parentLayer;
}
#property(monatomic, assign) CCNode *parentLayer;
-(id) initWithParent:(CCNode*)inParent;
#end
#implementation ParallaxBgTestLayer
-(id) initWithParent:(CCNode*)inParent
{
ParallaxBgTestLayer *obj = [ParallaxBgTestLayer node];
obj.parentLayer = inParent;
return obj;
}
-(void)CallMethodInGamePlayLayer
{
[((DigGameplayLayer*)( (MainClass*)self. parentLayer).gameplayLayer functionInGamePlayLayer];
}
#end
#interface DigGameplayLayer
{
CCNode *parentLayer;
}
#property(monatomic, assign) CCNode *parentLayer;
-(id) initWithParent:(CCNode*)inParent;
#implementation DigGameplayLayer
-(id) initWithParent:(CCNode*)inParent
{
DigGameplayLayer *obj = [DigGameplayLayer node];
obj.parentLayer = inParent;
return obj;
}
-(void) functionInGamePlayLayer
{
}
#end
I would be doing it by using the following steps;
Update/Override the init method of your DigGameplayLayer in order to get one more parameter ParallaxBgTestLayer
For example rename your gameplay init method as DigGameplayLayer initOnBackground:(ParallaxBgTestLayer *) backgroundLayer
import the ParallaxBgTestLayer.h in the implementation file of DigGameplayLayer
Access to any local variables of ParallaxBgTestLayer (the variables those you added into the ParallaxBgTestLayer.h file)
I think this is better than creating a singleton object if you only need to access from one location. I use singleton when I need them in more than one places in my apps.
I hope, this helps...
Related
I have a strange problem in my Cocoa-app. I have a main window with an NSTableView in it with a controller class (PropValTableHandler). I have made the connections between my NSTableView and the PropValTableHandler, but when the 'numberOfRowsInTableView' method is called it looks like not the 'PropValTableHandler' initialized in 'AddDelegate' is used, since the 'propMan' field is not initialized (it is like the normal init is used, so it has to be another instance of this class).
Am I doing something wrong? I have another NSTableView handler in another window, that works, but it does not have a custom init method.
Source codes:
AppDelegate
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize propValTableController = _propValTableController;
-(id) init
{
self = [super init];
if (self)
{
_propMan = [[OCPropertyManager alloc]initWithPath:"./data/"];
_propValTableController = [[PropValTableHandler alloc]
[initWithPropManager:_propMan];
}
return self;
}
PropValTableHandler
#interface PropValTableHandler : NSObject <NSTableViewDataSource>
#property IBOutlet NSTableView * constants;
#property OCPropertyManager * propMan;
-(id) initWithPropManager:(OCPropertyManager*)pm;
-(NSInteger) numberOfRowsInTableView:(NSTableView *)tableView;
#end
#import "PropValTableHandler.h"
#implementation PropValTableHandler
-(id) initWithPropManager:(OCPropertyManager*)pm
{
self = [super self];
if (self)
{
self.propMan = pm;
}
return self;
}
/*********** TABLEVIEW DATASOURCE ******************/
-(NSInteger) numberOfRowsInTableView:(NSTableView *)tableView
{
NSInteger count = [_propMan.consts count];
return count;
}
/**************************************************/
#end
I have solved the problem by adding a
#property IBOutlet AppDelegate *parent;
for the PropValTableHandler class and making the connections.
This way I can use:
parent.propMan
where ever I need it without passing a reference to it in the init method.
i need to build an application that define an array that should be made of image items.
every image iten has an image, a name and a photographer name.
i build my image item class and i want you to check if my define is correct and good(i just start to learn objective c).
i want you to emphasize on the set's methods.
here is the photoitem.h:
#import <Foundation/Foundation.h>
#interface photoItem : NSObject
{
UIImage *imageView;
NSString *photoNameLabel;
NSString *photographerNameLabel;
UIButton *viewPhoto;
}
#property(readonly) NSString *name;
#property(readonly) NSString *nameOfPhotographer;
#property(readonly) UIImage *imageItem;
-(id)makePhotoItemWIthPhoto:(UIImage*)image name:(NSString*)photoName photographer: (NSString*)photographerName;
#end
here is my photoitem.m:
#import "photoItem.h"
#implementation photoItem
#synthesize name;
#synthesize nameOfPhotographer;
#synthesize imageItem;
-(id)makePhotoItemWIthPhoto:(UIImage*)image name:(NSString*)photoName photographer:(NSString*)photographerName
{
[self setName:photoName];
[self setNameOfPhotographer:photographerName];
[self setImageItem:image];
return self;
}
-(void) setName:(NSString *)name
{
photoNameLabel = name;
}
-(void) setNameOfPhotographer:(NSString *)nameOfPhotographer
{
photographerNameLabel = nameOfPhotographer;
}
-(void)setImageItem:(UIImage *)imageItem
{
imageView = imageItem;
}
#end
i hope you could fix my errors(if there are some).
thanks.
Two problems come to mind:
1) -(id)makePhotoItemWIthPhoto:name:photographer: might be better as -(id)initWithPhoto:name:photographer:. Otherwise the caller needs to alloc and init an object first so that self is valid, then call your method. At that point, the return of self doesn't make sense.
Example:
-(idinitWithPhoto:(UIImage*)image name:(NSString*)photoName photographer:(NSString*)photographerName {
self = [super init];
if (self) {
[self setName:photoName];
[self setNameOfPhotographer:photographerName];
[self setImageItem:image];
}
return self;
}
2) The three readonly properties don't seem to have any purpose since they have no connection to the variables that you initialize in the makePhotoItemWIthPhoto: method.
I wanna do pass by reference in ObjC.
Here is the illustration of the scenario:
// MainClass.h
#interface MainClass
{
Board *board;
OtherClass *other;
}
#end
// MainClass.m
#implementation MainClass
- (id)init
{
if (self = [super init])
{
board = [[Board alloc] init];
other = [[OtherClass alloc] initOtherClassWithBoard: board];
}
return self
}
#end
// Other class.h
#interface OtherClass
{
Board *refBoard;
}
- (void)initOtherClassWithBoard: (Board*)ref;
#end
#implementation OtherClass
- (id)initOtherClassWithBoard: (Board*)ref
{
if (self = [super init])
{
refBoard = ref;
}
return self;
}
#end
So my question is does my OtherClass is holding a reference Board from MainClass?
Or OtherClass's Board is a copy but not a reference.
If I wanna do a reference then how should I change it?
EDIT:
What if I add this on both classes
#property (nonatomic, retain) Board *board;
You always refer to objects in Objective-C via pointers, a.k.a. references. Therefore, objects are always passed by reference in Objective-C.
It's a reference. It won't be a copy unless you do something to make it a copy (like use #property (copy) or send it a copy message).
I have the following class:
#interface Gamer {
...
}
+(id) CreatePlayer;
#end
#implementation Gamer
+(id) CreatePlayer
{
return [[[self alloc] init]autorelease];
}
#end
I need to use the Gamer in an another class as instance variable.
For example like this:
#interface Layer{
Gamer * mCenterGamer;
}
#end
#implementation
-(void) init{
mCenterGamer = [Gamer CreatePlayer];
}
-(void) exampleFuncForUseGamer{
[mCenterGamer ...]// some methods of the Gamer class
}
#end
Is it correct? (I think autorelease freed the mCenterGamer after exiting from the init function)
You need to retain mCenterGamer (and make sure to release it in the Layer's -dealloc method). Also, -init needs id as its return type:
- (id)init {
if (self = [super init])
mCenterGamer = [[Gamer CreatePlayer] retain];
return self;
}
- (void)dealloc {
[mCenterGamer release];
[super dealloc];
}
Your -exampleFuncForUseGamer should be fine, depending on what you're trying to do there.
I have a class called "CardSet", containing an NSMutableArray* cardSet to hold "cards", which I extend to make "DeckCards". I'd like "CardSet" to have a method called "(void)addCard:(Card*)" (and similarly a method "removeCard"). I'd like "addCard" to some how have access to and set cardSet. Even better I'd like to use the "addCard" method to initialise cardSet. The class file "CardSet.h" reads:
#import < Cocoa/Cocoa.h >
#import < Card.h >
#interface CardSet : NSObject {
NSMutableArray* cardSet;
}
-(id)init;
-(NSMutableArray*)getCardSet;
-(void)setCardSet:(NSMutableArray *)new_cardset;
-(Card*)getCard:(NSInteger) index;
**-(void)addCard:(Card*) new_card;**
-(void)removeCard:(Card*) old_card;
-(void)dealloc;
#property (readwrite, retain, getter=getCardSet, setter=setCardSet) NSMutableArray* cardSet;
#end
and the method file reads:
#import "CardSet.h"
#implementation CardSet
-(id)init{
if( self = [super init] ){} //will add initialisations here later
return self;
}
-(NSMutableArray*)getCardSet{
return cardSet;
}
-(void)setCardSet:(NSMutableArray *)new_cardSet{
cardSet = new_cardSet;
}
-(Card*)getCard:(NSInteger)index{
return [cardSet objectAtIndex:index];
}
**-(void)addCard:(Card *)new_card{
[cardSet addObject:new_card];
}**
-(void)removeCard:(Card *)old_card{
[cardSet removeObject:old_card];
}
-(void)dealloc{
[cardSet release];
[super dealloc];
}
#synthesize cardSet;
#end
This compiles just fine. I'd like to initialise a "DeckCards" instance using its "addCard" method 52 times. When I call addCard 52 times in a DeckCards setter method, and ask for the size of its "cardSet", I'm returned 0.
This appears to be a scope or privileges problem? Can the "addCard" method have any setter privileges? Must a setter argument be the same as the return and respective member type?
[I can work around the above by creating an NSMutableArray object "deck_cards_temp" outside of "DeckCard", add 52 cards to this, and pass it to set the member of my "DeckCards" instance via the setter inherited from "CardSet". This is not very satisfactory!]
What do you advise? Many thanks in advance for your help and patience.
You are never actually creating the cardSet object. You should be creating it in your -init method:
-(id)init
{
if( self = [super init] )
{
cardSet = [[NSMutableArray alloc] init];
}
return self;
}
Because you never actually create the array, all the calls to -addCard: are being sent to a nil object.
When you pass in an array to -setCardSet:, you are passing in an initialized array so the array is no longer nil and the -addCard: calls work fine.
CardSet.h
#import <Cocoa/Cocoa.h>
// For know we just need to know there is a class named "Card" being used but implemented later
#class Card;
#interface CardSet : NSObject {
NSMutableArray *cardSet;
}
// Here are the methods according to "correct" naming conventions
- (Card *)cardAtIndex:(NSInteger)index;
- (void)addCard:(Card *)card;
- (void)removeCard:(Card *)card;
// This will help us and forget about writing the setter/getter
#property (nonatomic, retain) NSMutableArray *cardSet;
#end
CardSet.m
#import "CardSet.h"
// Now we tell the compiler what "Card" is and what methods etc. it has
#import "Card.h"
#implementation CardSet
#synthesize cardSet;
- (id)init {
if (self = [super init]) {
// If we don't create the cardSet, how are we able to work with it!?
NSMutableArray *anArray = [[NSMutableArray alloc] init];
self.cardSet = anArray;
[anArray release];
}
return self;
}
- (Card *)cardAtIndex:(NSInteger)index {
return [cardSet objectAtIndex:index];
}
- (void)addCard:(Card *)card {
[cardSet addObject:card];
}
- (void)removeCard:(Card *)card {
[cardSet removeObject:card];
}
- (void)dealloc {
[cardSet release];
[super dealloc];
}
#end
As Abizern already noted: Naming the array the same as your class is a bad thing.
I would shorten that init method:
- (id)init {
if (self = [super init]) {
// If we don't create the cardSet, how are we able to work with it!?
self.cardSet = [NSMutableArray array];
}
return self;
}