sorry if this question has already come up but I couldn’t find anything that addressed the specific problem I’m having here.
I’m working in objective-c on iOS and I have declared an NSMutableDictionary instance variable, a property for it, synthesized it, and allocated space for it in my init method:
SettingsViewController.h
@interface SettingsViewController : UITableViewController <UIAlertViewDelegate> {
NSMutableDictionary *settingsData;
UISwitch *emailSwitch;
UISwitch *phoneSwitch;
NSMutableData *receivedData;
}
@property (nonatomic, retain) NSMutableDictionary *settingsData;
@property (nonatomic, retain) UISwitch *emailSwitch;
@property (nonatomic, retain) UISwitch *phoneSwitch;
@property (nonatomic, retain) NSMutableData *receivedData;
SettingsViewController.m init method
@synthesize settingsData, emailSwitch, phoneSwitch, receivedData;
# the initialization method, where settingsData is allocated
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
self.navigationItem.title = @"Settings";
[[self navigationItem] setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneEditing:)] autorelease]];
settingsData = [[NSMutableDictionary alloc] init];
}
return self;
}
The potion of the method in SettingsViewController.m that uses settingsData (it’s just a very simple parser for a block of data formatted key=value&):
NSMutableString *element = [NSMutableString string];
NSMutableString *value = [NSMutableString string];
bool cap_element = true;
char index;
for (int i = 0; i < [response length]; i++) {
index = [response characterAtIndex:i];
if (cap_element && index != '=') {
[element appendFormat:@"%c", index];
continue; // skip back to the top
}
if (index == '=') {
cap_element = false;
continue;
}
if (!cap_element && index != '&') {
[value appendFormat:@"%c", index];
continue;
}
if (index == '&') {
// store the value in the dict and move onto the next element
# this output is always correct...
NSLog(@"Key:%@, Value:%@", element, value);
[self.settingsData setObject:value forKey:element];
# ...as is this (the value printed above matches the result here)
NSLog(@"Result:%@", [settingsData objectForKey:element]);
[value setString:@""];
[element setString:@""];
cap_element = true;
}
# but this will output an empty string (username prints correctly above)
NSLog(@"%@", [self.settingsData objectForKey@"username"]);
The first 2 NSLog() comments output as expected, but as soon as I leave the for loop all of the keys remain and their values become empty strings (so output reads username = “” instead of username = “tester”). I would understand this if the dictionary was not initialized, but I take care of that in the init method shown above. What am I missing?
In the dictionary you are storing a reference to the “value” and “element” variables, not a copy. When you set them to empty string:
you also are updating the values in the dictionary as well.
EDIT: To solve, change this line:
to this to create new strings (stringWithString should give you autoreleased values):