2

I know this is simple, which is why I've been trying like mad to figure it out myself but I'm at the end of my rope.

When a user clicks a button an action is supposed to do this:

- (IBAction)startAction:(id)sender {
MyClass *anInstance = [[MyClass alloc] init];
NSLog(@"the name is:%@", [anInstance name]);

As you can see, MyClass has the "name" method, which is this:

- (NSString *)name {
return [nameInput stringValue];
NSLog(@"stringValue = %@", [nameInput stringValue]);

nameInput is a text field which the user fills with a name, presses the button to call "startAction", that method should call "name" in another class, which should return the string value from the text field and make the logs.

What is actually happening is that when start is pressed the log says "the name is:(null)". And the second log doesn't even appear. I assume it's because the "name" method isn't getting called. But I don't know why. I should specify that they are in separate classes and I declared the "name" method like this:

- (NSString*)name;

EDIT: After a bit more fooling around I found that when the "name" method gets called from it's own class, the log correctly shows whatever was in the text field. I put an extra log inside the "name" method, and I can see that it is getting called from the other class, but the value it's returning is still (null) which means something is happening after the call that is preventing the class from getting the text field string.

EDIT: I'm not sure if this is important but one of the classes is a subclass of NSObject, the other is a subclass of NSViewController.

Let me know if you need any more information. Thanks for the help.

Elbimio
  • 1,041
  • 2
  • 10
  • 25

3 Answers3

3

In the name method, you can't return a value before the NSLog() command -- returning from the method is the last thing that happens in the method (I'm surprised you don't get a warning about the NSLog() function not getting called). Try this instead:

- (NSString *)name {
    NSLog(@"stringValue = %@", [nameInput stringValue]);
    return [nameInput stringValue];
}

As for why nameInput does not have a value, I'm guessing you haven't properly connected the text field correctly in Interface Builder.

Chris Gregg
  • 2,376
  • 16
  • 30
  • Fixing the order now makes them both appear, but they still only show (null), even after linking it again – Elbimio Aug 08 '11 at 02:29
2

I'm not sure this is the correct answer because you haven't fully explained where nameInput comes from and how it gets its value. But I'm guessing it's an instance variable of MyClass. In startAction: you create a new instance of MyClass. Does the init method of MyClass also initialize nameInput? Since alloc initializes the instance variables to nil (or 0, 0.0, ... depending on the type), and if your init method does not assign any other value to nameInput, it will still be nil at the point when startAction: sends name to the new MyClass instance. Sending a message to nil in Objective-C in most cases returns nil (*), so sending stringValue to nameInput in this case returns nil and hence you get the (null) output in your log.

(*) For more info, see my answer to the question "Sending a message to nil?"

Community
  • 1
  • 1
Rinzwind
  • 1,173
  • 11
  • 23
  • This makes sense. nameInput is a textfield, the value comes from a user input. I added [nameInput init] to the init method, but it's still not working. – Elbimio Aug 08 '11 at 19:05
  • 1
    If that line is all you added, it's just going to be sending `init` to `nil`. You may want to (re-)read Xcode's documentation on “Allocating and Initializing Objects.” I don't mean to give offense if you're not, but it does seem like you are a beginning (Objective-C) programmer. I strongly recommend you learn Smalltalk first. It's easier to learn, and because Objective-C is heavily based on it, you can later ease into taking on the extra complexities of Objective-C. A good starting point is Pharo's “Get started now” download: http://www.pharo-project.org/ – Rinzwind Aug 09 '11 at 08:41
0

Your

- (NSString *)name {
return [nameInput stringValue];
NSLog(@"stringValue = %@", [nameInput stringValue]);

belongs to

MyClass *anInstance = [[MyClass alloc] init];

To which, I believe, nameInput is not part of it.

May be try adding a textField parameter to the name method and pass your nameInput to MyClass like

- (IBAction)startAction:(id)sender {
MyClass *anInstance = [[MyClass alloc] init];
NSLog(@"the name is:%@", [anInstance name:nameInput]);

Hope this helps.

Saran
  • 6,274
  • 3
  • 39
  • 48