Переменная экземпляра NSMutableDictionary не сохраняет значения ключа вне цикла - PullRequest
2 голосов
/ 13 июля 2011

извините, если этот вопрос уже возник, но я не смог найти ничего, что решило бы конкретную проблему, с которой я столкнулся.

Я работаю в target-c на iOS, и я объявил переменную экземпляра 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 метод инициализации

@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 (это просто очень простой анализатор для блока данных, отформатированный ключ = значение &):

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"]);

Первые 2 комментария NSLog () выводятся, как и ожидалось, но как только я ухожу из цикла for, все ключи остаются, и их значения становятся пустыми строками (поэтому выходные данные читают username = "" вместо username = "tester") , Я бы понял это, если бы словарь не был инициализирован, но я позабочусь об этом в методе init, показанном выше. Чего мне не хватает?

Ответы [ 3 ]

2 голосов
/ 13 июля 2011

В словаре хранится ссылка на переменные "value" и "element", а не копия.Когда вы устанавливаете для них пустую строку:

[value setString:@""];
[element setString:@""];

, вы также обновляете значения в словаре.

РЕДАКТИРОВАТЬ: Чтобы решить, измените эту строку:

[self.settingsData setObject:value forKey:element];

для этого, чтобы создать новые строки (stringWithString должен дать вам автоматически выпущенные значения):

[self.settingsData setObject: [NSString stringWithString: value] forKey: [NSString stringWithString: element]];
0 голосов
/ 13 июля 2011

Здесь вы устанавливаете значения двух строк на "":

[value setString:@""];
[element setString:@""];

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10 имеет только ссылки на исходные объекты, поэтому сделанные вами изменения отражаются везде, где есть ссылка наэтот объект.copy изменяемые объекты являются общими, если вы хотите убедиться, что их значения не изменены под вами.

0 голосов
/ 13 июля 2011

Проблема заключается в следующем:

[value setString:@""];
[element setString:@""];

Вы устанавливаете элемент / значение на пустые строки после того, как в словаре указаны ссылки на оба.Словарь содержит ссылки, а не их значения.Из-за этого, когда вы изменяете значения элемента / значения, вы неожиданно (по крайней мере, в этом случае) изменили поведение вашего словаря так, что он больше не будет реагировать на заданный вами ключ и не будет возвращатьзначение, которое было изначально определено.

Если вы не хотите, чтобы это происходило, вам необходимо скопировать строки перед их сбросом.

...