Object Messaging in Cocoa

Joined
Mar 9, 2007
Messages
5
Reaction score
0
With no shortage of effort I still can't seem to wrap my head around the Object messaging. This is no usefull application but more a specific challenge I'm trying. I have the window of the Main Nib file set with one button (NSButton) and one text field (NSTextField). When the button is pressed I would like the field to display a string. However, I seek to do this with two seperate subclasses of (NSObject), I've named AFirstClass and ASecondClass. When the button is pressed I would like it to call a method of AFirstClass that calls a method of ASecondClass that displays the string. Both Classes have been instantiated, The button is "connected" with the action messageToSecondAct: and ASecondClass is "connected" with an outlet of type NSTextfield titled textOut. eg. "connections" have been made.

When I build and run the program it goes smoothly until I click the button. There is no response but the run log displays:

2007-03-09 11:03:51.910 HelpExample[5283] *** +[ASecondClass writeOnCommand]: selector not recognized

I understand coding or debugging isn't very enjoyable but I've tried to simplify my problem, and I believe the answer is probably imediatly obviose to the more accomplished. I have included the Interface and implementation files for both classes below:

/* AFirstClass */

#import <Cocoa/Cocoa.h>

@interface AFirstClass : NSObject
{
}

- (IBAction)messageToSecondAct:(id)sender;

@end



#import "AFirstClass.h"
#import "ASecondClass.h"

@implementation AFirstClass

- (IBAction)messageToSecondAct:(id)sender
{
[ASecondClass writeOnCommand];
}

@end



/* ASecondClass */

#import <Cocoa/Cocoa.h>

@interface ASecondClass : NSObject
{
IBOutlet NSTextField *textOut;
}

+ (void)writeOnCommand;

@end



#import "ASecondClass.h"

@implementation ASecondClass

+ (void)writeOnCommand
{
[textOut setStringValue:mad:"It worked"];
}

@end
 
Joined
Apr 2, 2007
Messages
2
Reaction score
0
When the button is pressed I would like it to call a method of AFirstClass that calls a method of ASecondClass that displays the string.

1 - The button needs to map to an action in AFirstClass.
2 - AFirstClass needs an outlet to ASecondClass.
3 - ASecondClass needs to have an action writeOnCommand

Seems to me like you haven't created the second part: The outlet from AFirstClass to ASecondClass. If you did then there should be something like this:
Code:
...
@interface AFirstClass : NSObject
{
  IBOutlet SecondAction* secondAction;
}
// .. etc

Also, from what I know, if you have a "+" in front of your method (
Code:
+ (void)writeOnCommand
) it means that it's not an instance method. Ie - you can't access instance variables of that class such as:
Code:
IBOutlet NSTextField *textOut;

I'm also new to Cocoa, but I hope this helps.
 
Joined
Mar 9, 2007
Messages
5
Reaction score
0
Thank You kindly for your reply, it makes sense to me but I could not get my revisions to compile. You are right, I hadn't taken the second step you give in your reply. I also switched the method to an instance method (-). The only change to the ASecondClass files. AFirstClass files now look as follows:


/* AFirstClass */

#import <Cocoa/Cocoa.h>

@interface AFirstClass : NSObject
{
IBOutlet ASecondClass* aSecondClassOut;
}

- (IBAction)messageToSecondAct:(id)sender;

@end



:confused: #import "AFirstClass.h"
#import "ASecondClass.h"

@implementation AFirstClass

- (IBAction)messageToSecondAct:(id)sender
{
:confused: [aSecondClassOut writeOnCommand];
}

@end

I've noted the places that the compiler does not like with the confused faces.

For the First error it gives the explanation:
error: parse error before 'ASecondClass'
Have I not used the proper syntax to include two headers?

The Second error reads as follows:
error: 'aSecondClassOut' undeclared (first use in this function)
I don't know how this is possible. The outlet has been declared in the header file and a control click drag from AFirstClass to ASecondClass to "Connect" the two Class Instances in Interface Builder worked.

I think your revisions make perfect sense and should be the solution to my problem, but the compiler doesn't like it, and I have little understanding why.
 
Joined
Mar 9, 2007
Messages
5
Reaction score
0
I don't know why the purple faces are there, please disregard. To elaborate I've made a simple craps game. with multiple ways to "win" I would like to code the "win" protocal only once and call it from different places in the app. I'm not really sure I'm headed in the right dirrection at all. I'm somewhat familiar with c# and the .net IDE where I was able to simply write a "win" function and call it from other places. From what I understand about Cocoa and Objective-C you would make a class that contains this "win" function/method, create an instance of the class, and tell it to run the method. I'm worried I can't properly conceptualize object oriented programming paradigms and working backwards. I prefer my mac and would like to write apps for the MacOS but this is a significant hurdle I must overcome first.
 

Ric

Joined
May 14, 2004
Messages
4,260
Reaction score
5
Way over my head !

But feel free to talk amongst yourselves !!!

;-)

Off to find my Objective c book

Welcome to both of you !

regards

Ric
 
Joined
Mar 9, 2007
Messages
5
Reaction score
0
Well I'm still at it and would like to share my congress (I think I'm regressing). Despite that, I am able to get the following to compile but the program is unresponsive (no effect of button press).

To sum up my revisions, I made changes relative to my statement of 2 weeks ago:

From what I understand about Cocoa and Objective-C you would make a class that contains this "win" function/method, create an instance of the class, and tell it to run the method.

After implementing that (ASecondClass *aSecondClassInst), I deleted the single IBOutlet declaration in the AFirstClass Interface file that was linked to the ASecondClass Instance in IB. I no longer think the instances of these classes in IB need to be connected. They are still connectected to the rest of the Interface however (Button -> AFirstClass & ASecondClas -> *textOut). That got rid of the error: "parse error before 'ASecondClass'" that I had detailed two weeks previouse. I don't rely understand why but I draw my conclusion through cause and effect.

So now I have a compilable pile who's resulting application's sole user interface element is unresponsive:

/* AFirstClass */

#import <Cocoa/Cocoa.h>

@interface AFirstClass : NSObject
{
//Declaration was buggin out
}

- (IBAction)messageToSecondAct:(id)sender;

@end


#import "AFirstClass.h"
#import "ASecondClass.h"

@implementation AFirstClass

- (IBAction)messageToSecondAct:(id)sender
{
ASecondClass *aSecondClassInst;
aSecondClassInst = [[ASecondClass alloc] init];
[aSecondClassInst writeOnCommand];
}

@end


/* ASecondClass */

#import <Cocoa/Cocoa.h>

@interface ASecondClass : NSObject
{
IBOutlet NSTextField *textOut;
}

- (void)writeOnCommand;

@end


#import "ASecondClass.h"

@implementation ASecondClass

- (void)writeOnCommand
{
[textOut setStringValue:mad:"It worked"];
}

@end


To restate my question,

"How do I write a method that calls upon another object's method"

I understand this to be similiar to nested functions. I don't need this example to work, I understand it might be backwards. I've written it only to showcase my dilema in brevity.
 
Joined
Nov 26, 2010
Messages
3,558
Reaction score
52
You are instantiating ASecondClass.h in your NIB so when you make one in messageToSecondAct you are making a second one, this is not the object you're looking for.

There are all manner of ways to deal with this.
The easiest would be to also add AFirstClass to your nib and Wire them together.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top