我在iOS上的objective-c工作,我已经声明了一个NSMutableDictionary实例变量,它的一个属性,合成它,并在我的init方法中为它分配空间:
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方法
@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;
}
SettingsViewController.m中使用settingsData的方法的部分(它只是一个非常简单的解析器,用于格式化数据块的键=值&amp;):
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"]);
前两个NSLog()注释按预期输出,但是一旦离开for循环,所有键都保留,并且它们的值变为空字符串(因此输出读取username =“”而不是username =“tester”) 。如果没有初始化字典我会理解这一点,但是我在上面显示的init方法中处理了这个问题。我错过了什么?
答案 0 :(得分:2)
在字典中,您存储对“值”和“元素”变量的引用,而不是副本。当您将它们设置为空字符串时:
[value setString:@""];
[element setString:@""];
你也在更新字典中的值。
编辑:要解决,请更改此行:
[self.settingsData setObject:value forKey:element];
来创建新的字符串(stringWithString应该给你自动释放的值):
[self.settingsData setObject: [NSString stringWithString: value] forKey: [NSString stringWithString: element]];
答案 1 :(得分:0)
问题在于:
[value setString:@""];
[element setString:@""];
在给予两者的字典引用后,您将元素/值设置为空字符串。字典保留了那些引用,而不是它们的值。因此,当您更改元素/值时,您会意外地(至少在这种情况下)更改字典的行为,因为它不再响应您设置的键并且它不会返回最初定义的值。
如果您不希望发生这种情况,则需要在重置之前复制字符串。
答案 2 :(得分:0)
您在此处将两个字符串的值设置为“”:
[value setString:@""];
[element setString:@""];
NSMutableDictionary
仅对原始对象有引用,因此您所做的更改会反映在对该对象的引用的位置。如果您想确保在您下面没有更改值,那么copy
可变对象很常见。