简体   繁体   中英

Cannot append to empty string

In my project, I need to accept user input from textboxes, then format that input, then append the formatted input to another string which is a URL I will later submit.

My textboxes are inputZip, inputCity, inputState and the input will be saved in a string called location. When the input is in the zip code field, it saves the contents of the textbox to location and works fine. When the input is city/state, I need to format the input from the two textboxes as "state/city", but I can't get location to format and save that info, it just stays blank. This is my code so far, with notes.

@interface ViewController ()
- (IBAction)btnSubmit:(id)sender;
@property (weak, nonatomic) IBOutlet UITextField *inputZip;
@property (weak, nonatomic) IBOutlet UITextField *inputCity;
@property (weak, nonatomic) IBOutlet UITextField *inputState;

@property NSString *location;
@property NSMutableString *queryURL;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.location = [[NSString alloc]init];
    self.queryURL = [[NSMutableString alloc]initWithString:@"http://api.wunderground.com/api/api-key/forecast/q/"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)btnSubmit:(id)sender {
    // IF inputZip is not empty
        // assign location
    // ELSE inputCity + inputState = ST/City
        // assign location
    // call getWeather(location)

    // clear previous location
    self.location = nil;

    if (self.inputZip != nil){
        self.location = self.inputZip.text;
        //self.location = [NSString stringWithFormat:@"%@",self.inputZip.text];
        // both of these lines work fine
    }else{
        //self.location = [NSString stringWithFormat:@"%@/%@", self.inputState, self.inputCity];
        //self.location = [NSString stringWithFormat:@"%@/%@", self.inputState.text, self.inputCity.text];
        [self.location stringByAppendingString:self.inputState.text];
        [self.location stringByAppendingString:@"/"];
        [self.location stringByAppendingString:self.inputCity.text];
        // none of these approaches work, location comes up empty each time
    }

    // print variables to check them
    NSLog(@"zip = %@", self.inputZip.text);
    NSLog(@"city = %@", self.inputCity.text);
    NSLog(@"state = %@", self.inputState.text);
    NSLog(@"loc = %@", self.location);
    NSLog(@"--------------------");
}

-(void) getWeather:(NSString*)location{
    // build query using location
    // submit query
    // update results page
}
@end

I wonder if it's not working because the zip field is not nil, if it's considering it as an empty string, but if that's the case it shouldn't even look at the city and state fields. I'm stuck.

For fun, this is my output:

2014-10-23 15:12:45.738 WeatherApp[33763:1934020] zip = 12345
2014-10-23 15:12:45.738 WeatherApp[33763:1934020] city = 
2014-10-23 15:12:45.739 WeatherApp[33763:1934020] state = 
2014-10-23 15:12:45.739 WeatherApp[33763:1934020] loc = 12345
2014-10-23 15:12:45.739 WeatherApp[33763:1934020] --------------------
2014-10-23 15:12:50.495 WeatherApp[33763:1934020] zip = 
2014-10-23 15:12:50.495 WeatherApp[33763:1934020] city = CHICAGO
2014-10-23 15:12:50.495 WeatherApp[33763:1934020] state = IL
2014-10-23 15:12:50.495 WeatherApp[33763:1934020] loc = 
2014-10-23 15:12:50.496 WeatherApp[33763:1934020] --------------------

You have two problems in your code, the first is that you send messages to nil and the second is that you discard the modified string.

Sending messages to nil

Just before the if-statement you set your property to nil .

// clear previous location
self.location = nil;

As you might know, sending messages to nil does nothing. So, a few lines down when you call

[self.location stringByAppendingString:self.inputState.text];

you are actually calling

[nil stringByAppendingString:self.inputState.text];

which does nothing. If you want to clear the previous value as the comment says you can set the property to an empty string instead.

// clear previous location
self.location = @"";

Discarding the modified string

If you look closer at the documentation you will see that stringByAppendingString: does not modify the string (you are using a immutable string after all) but instead returns a new string:

- stringByAppendingString:

Returns a new string made by appending a given string to the receiver.

That code should either have been:

self.location = [self.location stringByAppendingString:self.inputState.text];
self.location = [self.location stringByAppendingString:@"/"];
self.location = [self.location stringByAppendingString:self.inputCity.text];

or you should use a mutable string instead:

NSMutableString *mutableString = [self.location mutableCopy]; // a mutable copy
[mutableString appendString:self.inputState.text];
[mutableString appendString:@"/"];
[mutableString appendString:self.inputCity.text];
self.location = [mutableString copy]; // make an immutable copy again

- stringByAppendingString:

Returns a new string made by appending a given string to the receiver.

and you discard the new string... need to assign it back to self.location

self.location = [self.location stringByAppendingString:self.inputState.text];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM