NSMutableDictionary 实例变量不保留循环外的键值

发布于 2024-11-23 20:27:30 字数 2772 浏览 0 评论 0原文

很抱歉,如果这个问题已经出现,但我找不到任何可以解决我在这里遇到的具体问题的内容。

我正在 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 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;
}

该方法的部分在使用 settingsData 的 SettingsViewController.m 中(它只是一个非常简单的解析器,用于格式化 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"]);

前 2 个 NSLog() 注释按预期输出,但是一旦我离开for 循环保留所有键,并且它们的值变成空字符串(因此输出读取 username = "" 而不是 username = "tester")。如果字典未初始化,我会理解这一点,但我在上面显示的 init 方法中处理了这一点。我缺少什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野心澎湃 2024-11-30 20:27:30

在字典中,您存储对“值”和“元素”变量的引用,而不是副本。当您将它们设置为空字符串时:

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

您也正在更新字典中的值。

编辑:要解决此问题,请将这一行更改为:

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

以此来创建新字符串(stringWithString 应该为您提供自动释放的值):

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

In the dictionary you are storing a reference to the "value" and "element" variables, not a copy. When you set them to empty string:

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

you also are updating the values in the dictionary as well.

EDIT: To solve, change this line:

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

to this to create new strings (stringWithString should give you autoreleased values):

[self.settingsData setObject: [NSString stringWithString: value] forKey: [NSString stringWithString: element]];
等待圉鍢 2024-11-30 20:27:30

您在此处将两个字符串的值设置为“”:

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

NSMutableDictionary 仅引用原始对象,因此您所做的更改会反映在引用该对象的任何位置。如果您想确保您下面的值不会更改,那么复制可变对象是很常见的。

You are setting the values of the two string to "" here:

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

The NSMutableDictionary only has references to the original objects so changes you make are reflected where ever there is a reference to that object. It is common to copy mutable objects if you want to ensure that there values are not changed underneath you.

风透绣罗衣 2024-11-30 20:27:30

问题在于:

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

在给元素/值提供了字典引用之后,您将元素/值设置为空字符串。字典保存的是这些引用,而不是它们的值。因此,当您更改元素/值值时,您会意外地(至少在本例中)更改字典的行为,因为它不再响应您设置的键,也不会返回最初定义的值。

如果您不希望发生这种情况,则需要在重置字符串之前复制它们。

The problem lies here:

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

You're setting element/value to empty strings after you've given the dictionary references to both. The dictionary is holding onto those references, not their values. Because of this, when you change the element/value values, you're unexpectedly (at least in this case) changing the behavior of your dictionary in that it no longer will respond to the key you've set and it will not return the value that was initially defined.

If you don't want this to happen, then you need to copy the strings before you reset them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文