views:

52

answers:

2

I have a method that gets called any time a control on my view changes and should update a UILabel. It has two UITextFields and two UISliders. First I check to see if either of the UITextFields are empty and if so, advise that they need to be filled in. Otherwise I get the difference between the UITextFields' values and generate a couple of floats to use in my NSStrings.

I get a warning that message is not used and I get an error about the NSStrings (can't remember now exactly what - I'm not at my Mac...)

And even when I chopped the messages down to something simple that worked, when delta == 0, it does the delta <= 0 message.

Oh, and the strings don't put the values in where the % signs are, they just print the % signs.

I've been hacking at this too long and need help...

- (void)updateAdvice {
    if ([chlorineSourceField.text isEqualToString:@""] || [poolVolumeField.text isEqualToString:@""]) {
        NSString *message =  [[NSString alloc] initWithString:@"Enter a chlorine source and pool volume."];
    }
    else {
        int delta = [targetLabel.text intValue] - [startingLabel.text intValue];
        float chlorineAmount = delta * [poolVolumeField.text intValue] * chlorineConstant;
        float percentRemove = (1 - ([targetLabel.text floatValue] / [startingLabel.text floatValue]));
        float gallonsRemove = percentRemove * [poolVolumeField.text intValue];
        if (delta == 0) {
            NSString *message = [[NSString alloc] initWithString:@"No adjustments necessary.  You're on target"];
        }
        if (delta >= 0) {
            NSString *message = [[NSString alloc] initWithFormat:@"To increase FC by %dppm, add %3.1f oz of %@.", delta, chlorineAmount, chlorineSourceField.text];
        }
        if (delta <= 0) {
            NSString *message = [[NSString alloc] initWithFormat:@"You're above target already.  Replace %d%% or %d gallons of water - or just wait for it to come down.", percentRemove*100, gallonsRemove];
        }
    }
    adviceLabel.text = message;
    [message release];
}
+1  A: 

As far as the message variable goes, it's scoped so it can't be used outside the if/else statement in which it is declared. You want to declare it before the if statement, so you can use it outside of the if statement. So something like this:

- (void)updateAdvice {
    NSString *message = nil;

    if ([chlorineSourceField.text isEqualToString:@""] || [poolVolumeField.text isEqualToString:@""]) {
        message =  [[NSString alloc] initWithString:@"Enter a chlorine source and pool volume."];
    }
    else {
        int delta = [targetLabel.text intValue] - [startingLabel.text intValue];
        float chlorineAmount = delta * [poolVolumeField.text intValue] * chlorineConstant;
        float percentRemove = (1 - ([targetLabel.text floatValue] / [startingLabel.text floatValue]));
        float gallonsRemove = percentRemove * [poolVolumeField.text intValue];
        if (delta == 0) {
            message = [[NSString alloc] initWithString:@"No adjustments necessary.  You're on target"];
        }
        if (delta >= 0) {
            message = [[NSString alloc] initWithFormat:@"To increase FC by %dppm, add %3.1f oz of %@.", delta, chlorineAmount, chlorineSourceField.text];
        }
        if (delta <= 0) {
            message = [[NSString alloc] initWithFormat:@"You're above target already.  Replace %d%% or %d gallons of water - or just wait for it to come down.", percentRemove*100, gallonsRemove];
        }
    }
    adviceLabel.text = message;
    [message release];
}
mipadi
Thanks! I'd never have figured that out without help! +1
Steve
+2  A: 

You are missing the else part, thus all three if statements are being evaluated consecutively. If delta == 0, it will satisfy all three if statements. Thus, the last allocation will overwrite the previous two. (And you'll be leaking memory)

Also, your message variable is scoped as local to the if block it's declared into. You might want to move the message declaration at the function level scope.

As far as % not working, you are using the instance initializer initWithFormat with the syntax for the class initializer stringWithFormat. initWithFormat takes the parameters for the formatted string in a separate parameter - arguments:. (Btw, it also requires locale:)

Franci Penov
Duh, I don't want less-than-OR-equal, just less-than. I'm new to the C world. Can I just use `<` and `>` in the condition? The `==` for equals throws me off =)And do you know why the %d stuff wouldn't work?
Steve
Yes, you can use just `<` and `>`. I'd still add the `else` to the `if` blocks - you don't need all three to be evaluated always. Nope, I don't know why the %d part is not working.
Franci Penov
Actually, I just figured out why the %d does not work. I'll update my answer.
Franci Penov
From my Beginning iPhone Development 3 book:`NSString *title = [sender titleForState:UIControlStateNormal]; ` `NSString *newText = [[NSString alloc] initWithFormat:@"%@ button pressed.", title]; ` This works and looks to me like what I'm doing. Except that I used `initWithString` instead of `initWithFormat` for the strings that didn't have any variable embedded.
Steve
I'd trust that Apple documentation is more correct than any book out there. :-) But if it works just fine, it's your call. From your post and your comments, I was under the impression that it in fact _does not_ work, though.
Franci Penov
When I said it worked, I meant that snippet in my comment works in the context of the sample program from the book - you're right in that my code does not work. I checked out Apple's documentation and see what you mean. They use `stringWithFormat:` in the way I am trying to make my strings. I'll try that tonight at home and see. Thanks again for the patient help.
Steve
Just FYI, Apple actually does have `initWithFormat` without requiring the `locale:` part. The problem I had with the `%d` turned out to be that the thing that `%d` represented was a `float` and once I changed them to `%1.1f` the worked.
Steve