2011-07-12 5 views
2

この問題が既に発生している場合は申し訳ありませんが、私がここにいる特定の問題に対処するものは見つかりませんでした。NSMutableDictionaryインスタンス変数がループ外のキー値を保持しない

私は、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; 
} 

settingsDataを使用SettingsViewController.m方法のポーション(それはチュですSTデータのブロックのための非常にシンプルなパーサフォーマットされたキー=値&):予想、しかし、すぐに私はループのためにすべてのキーを残すようが残るよう

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 [email protected]"username"]); 

最初の2のNSLog()コメント出力とそれらの値は空の文字列になります(したがって、username = "tester"の代わりにusername = ""と出力されます)。私は辞書が初期化されていない場合、これを理解するだろうが、私は上記のinitメソッドでそれを世話する。私は何が欠けていますか?

答えて

2

辞書では、コピーではなく、「値」と「要素」変数への参照を保存しています。空文字列に設定した場合:

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

また、辞書の値も更新しています。

EDITは:(stringWithStringあなたが値を自動解放与えるべきである)新しい文字列を作成するには、このへ

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

:変更、この行を解決するため

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

私の神は本当にありがとう、私はそれを逃したとは思えない – drodman

0

問題はここにある:

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

あなたは両方の辞書の参照を与えた後の文字列を空にする要素/値を設定しています。辞書はその値ではなく、それらの参照を保持しています。このため、要素/値の値を変更すると、予期しないことに(少なくともこの場合)、辞書の動作が変更され、設定したキーに応答しなくなり、最初に定義された値。

これが起こらないようにするには、文字列をリセットする前にコピーする必要があります。

+0

完全にお見逃し、ありがとうございます! – drodman

0

を次の2つの値を設定していますここでの文字列には "":

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

NSMutableDictionary参照のみのトンを持っています元のオブジェクトは、そのオブジェクトへの参照があった場所に反映されます。 copy変更可能なオブジェクトは、値が変更されていないことを確認したい場合には一般的です。

関連する問題