0

This is a common topic but, in my case there is one thing I don't understand that I can't find explained in the other asked questions.

Here is the gist of what I'm trying to do:

User clicks a button and something like this is called:

@implementation FirstClass
-(void)clickedButton
{
    [SecondClass changeText];
}

And then in SecondClass is:

@implementation SecondClass
- (void)changeText {
         [myLabel setText:@"text"];
}

So when the user clicks the button, the text property in myLabel in SecondClass changes to "text".

The only problem I have with this is calling [SecondClass changeText] on the existing instance of SecondClass. Since I'm not initializing the CCNodes programmatically (they are all automatically loaded upon running the app), I don't know where or how SecondClass is initialized. I'm using SpriteBuilder to build this project.

Any help would be appreciated. Thanks!

SaleenS7
  • 402
  • 4
  • 15
  • 1
    I am trying to figure out what you need to learn here... Maybe outlets? You don't want to initialize a new object, but some already exist, by your title I thought you needed to learn about Class methods... – Grady Player Oct 01 '14 at 00:39
  • 1
    Yeah, this one is a great mess, especially with [super init] part. Please describe what you are trying to achieve, because even presented efforts did not give any clue on that. :) – user3125367 Oct 01 '14 at 00:48
  • Please check the answer, I think, it is what you were looking for. – rudedude Oct 01 '14 at 01:00
  • Ahh my bad on the [super init], originally I was using `init` to set text of `myLabel` and then I switched it to `(void)changeText`. Too late at night I guess. What I am trying to achieve is: user clicks button, `clickedButton` gets called in `FirstClass`. `clickedButton` then calls `changeText` in `SecondClass`. `changeText` changes a labels text in `SecondClass` – SaleenS7 Oct 01 '14 at 01:03
  • What you describe can never happen, since `[SecondClass changeText];` is calling a class method, and `- (void)changeText` is declaring an instance method. – Hot Licks Oct 01 '14 at 01:30
  • Ok I understand that now, do you have any solution to accessing an instance variable from a class method? I know it's not possible to do directly, but are there any workarounds to access and instantiated label? – SaleenS7 Oct 01 '14 at 01:42

2 Answers2

0

So, you have two instaces -- one with a button, and one with a label. I'm assuming they are both descendants of NSViewController or otherwise manage underlying views.

The problem is, you found no way to address second instance containing label from the method of first instance.

You need to define a property in first instance's class:

@property(weak) SecondClass *secondInstance;

And then in button clicked method:

-(void)clickedButton
{
    [self.secondInstance changeText];
}

There is one issue left: who is responsible to set first instance's property that we defined? This depends on who did create both of them, probably just app delegate or enclosing controller, you know that better.

UPD: If both of the controllers are created by AppDelegate:

#import "FirstClass.h"
#import "SecondClass.h"

@interface AppDelegate ()

// case A - manual
@property(strong) FirstClass *firstInstance;
@property(strong) SecondClass *secondInstance;

// case B - declared in xib
//@property(weak) IBOutlet FirstClass *firstInstance;
//@property(weak) IBOutlet SecondClass *secondInstance;

@end

@implementation AppDelegate

...

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    // Create them
    self.firstInstance = [[FirstClass alloc] init...];
    self.secondInstance = [[SecondClass alloc] init...];
    // Or maybe they are declared in MainMenu.xib, then you do not create them
    // by hand, but must have outlets for both. See case B above.

    // Connect them
    self.firstInstance.secondInstance = self.secondInstance;

    ...
}

Note that class is not the same as an object (instance). Class is a named collection of methods, mostly for the instance. In Objective-C, class is not just a name, but an object too, so you can call a method on it (i.e. send an message to the class object). But here we always talk about objects (instances), so forget about classes – we hold objects via strong properties or weak outlets, depending on how they were created, and operate on objects, never on classes.

user3125367
  • 2,920
  • 1
  • 17
  • 17
  • Ah thank you. It is in app delegate that is creating both. So to set `secondInstance`, I understand that I need to set it from app delegate, but how do I refer to FirstClass from app delegate? App delegate does not create any code for initializing FirstClass, so I am not sure how to refer to it. I attempted to create a `@property FirstClass *firstClass` but obviously I need to set that property to `FirstClass` or else it will be nil. Setting the property to `FirstClass` is what I am trying to figure out how to do, because I need to define `FirstClass` to be able to access it's properties. – SaleenS7 Oct 01 '14 at 19:38
  • Figured it out with this: http://stackoverflow.com/questions/24759662/cocos2d-v3-ios-how-to-access-runningscene-from-app-delegate Appreciate it :) – SaleenS7 Oct 01 '14 at 20:02
  • One question: How exactly do I go about setting `secondInstance` from app delegate? It is something like `firstClass.secondInstance = ____` And in the blank would be SecondClass, but I am trying to figure out how to get SecondClass. If that makes sense. It's hard to explain – SaleenS7 Oct 01 '14 at 20:10
-2

In objective C, the methods are either instance methods or class methods. As the name suggests, the instance methods require an instance of the class to work, whereas the class methods can be used with just the name of the class. What you need here is a class method. Just change the following line in your code:

@implementation SecondClass
- (id)changeText {

to

@implementation SecondClass
+ (id)changeText {

This will change the method from an instance method to a class method.

rudedude
  • 723
  • 4
  • 18
  • I would use class methods but I can't use instance variables in them. Unless there is some sort of work around with that – SaleenS7 Oct 01 '14 at 01:01
  • You can pass the required variable as an argument to the method. – rudedude Oct 01 '14 at 01:05
  • Would it still be possible to pass in a CCLabelTTF? The dilemma is that I'm trying to update `myLabel` which is instantiated in `SecondClass`. It is instantiated as a `@property` in the header file. And I can't pass in `myLabel` from `FirstClass` – SaleenS7 Oct 01 '14 at 01:24
  • Remove the property from HeaderFile and define it as a global variable in your class file. That means declare it before @implementation. – rudedude Oct 01 '14 at 01:28
  • 2
    Simply doing what you describe will make `myLabel` inaccessible. – Hot Licks Oct 01 '14 at 01:32
  • Defining it as a global variable makes `myLabel` nil – SaleenS7 Oct 01 '14 at 01:35
  • You really need to have a look at how classes work. Please refer: http://rypress.com/tutorials/objective-c/classes.html – rudedude Oct 01 '14 at 01:57
  • @harsh.prasad totally agree with `Hot Licks` this isn't the way to be going -1. – Popeye Oct 02 '14 at 07:54