2012-02-16 7 views
0

jsonエンコードされたイベントのNSDictionaryを解析し、その月に基づいて2次元のNSMutableArrayに配置しています。NSMutableArrayをループから別のものに追加すると複製が作成される

私は配列に項目を追加してループ内の配列(event_container)に配列を配置しているので、正しい配列数が表示されますが、すべてが最後の繰り返しと重複しているようですevent_containerの内容は同じ配列です。

私はこれがポインタであり、リリースされていないためだと思います。私はこれを回避するための適切な方法がないか、場合によってはより良い解決策であるとは確信しています。私はARCを使用しています。

int month = 0; 
int current_month = 0; 
int counter = 0; 

event_container = [[NSMutableArray alloc] init]; 

temp_array = [[NSMutableArray alloc] init]; 


for (NSDictionary *result in results) 
{ 

    NCEvent *anEvent = [[NCEvent alloc] init]; 

    anEvent.title = [result objectForKey:@"title"]; 
    anEvent.startdate = [result objectForKey:@"startdate"]; 
    anEvent.enddate = [result objectForKey:@"enddate"]; 

    NSDateFormatter *importDate = [[NSDateFormatter alloc] init]; 
    [importDate setDateFormat:@"yyyy-M-d H:m:ss"]; 
    anEvent.dateStart = [importDate dateFromString:anEvent.startdate]; 
    anEvent.dateEnd = [importDate dateFromString: anEvent.enddate]; 

    NSDateFormatter *exportDate = [[NSDateFormatter alloc] init]; 
    [exportDate setDateFormat:@"d"]; 
    anEvent.text_date = [exportDate stringFromDate: anEvent.dateStart]; 

    NSDateFormatter *exportMon = [[NSDateFormatter alloc] init]; 
    [exportMon setDateFormat:@"MMM"]; 
    anEvent.text_mon = [exportMon stringFromDate: anEvent.dateStart]; 

    NSDateFormatter *monthInt = [[NSDateFormatter alloc] init]; 
    [monthInt setDateFormat:@"M"]; 
    month = [[monthInt stringFromDate: anEvent.dateStart] intValue]; 

    if(counter == 1){       //first month 
     current_month = month; 
     NSLog(@"I'm the first month: %i", month); 
     [temp_array addObject:anEvent]; 

    } 
    else if(month > current_month){    //new month 
     NSLog(@"This is a new month");      
     current_month = month; 

     //add the events array to events container and reset the events array 
     [self.event_container addObject: temp_array]; 

     [temp_array removeAllObjects]; 

     [temp_array addObject:anEvent]; 

    } 
    else{ 
     NSLog(@"Same Month");     //same month 
     [temp_array addObject:anEvent]; 


    } 

    NSLog(@"Event month integer: %i", month); 

    anEvent = nil; 

    counter++; 

} 

これらの配列プロパティとして宣言されている:ポインタであるアレイ約

@property (nonatomic, retain) NSMutableArray *event_container; 
@property (nonatomic, retain) NSMutableArray *temp_array; 
+0

すぎてループ内のコードのこの全体の塊ですか? –

+0

いいえ、関与している唯一のループです –

答えて

2

[self.event_container addObject: temp_array]; 

あなたはいつもself.event_containerに同じインスタンスtemp_arrayを追加しています。このため、同じ配列が何回も複製されていることがわかります。来て、コードを変更する - そしてループ

for (int i = 0; i < 12; i++) { 
    [event_container addObject:[NSMutableArray array]]; 
} 
for (NSDictionary *result in results) 
... 

-Remove

if(counter == 1){       //first month 
    current_month = month; 
    NSLog(@"I'm the first month: %i", month); 
    [temp_array addObject:anEvent]; 
} 

のためにあなたの前に、以下の-Add

あなたは、例えば次のようにしてこの問題を解決することができますそれ以降:

tmp_array = [event_container objectAtIndex:month]; 
[temp_array addObject:anEvent]; 
+0

ええ、これは完全に意味があります...しかし、もし私が月数を事前に知っていなければ、何か提案はありますか?ループの後にevent_containerに追加された空の配列を削除できますか? –

+0

私は必要に応じて飛行中にオブジェクトを追加してしまいました...完璧な作品、ありがとうございます –

+0

@JoshCaswell LOL ...あなたの助けもありがとう! –

1

あなたの疑惑は、基本的には正しいです。問題は、temp_arrayが一時的ではないことです。実際には、毎回同じ配列オブジェクトが繰り返し使用されます。

ループ外で作成していて、addObject:または​​を送信すると、それはすでにそこに配置されているものに影響します。

しかし、重要な部分は、temp_arrayevent_containerに追加すると、それはまったく同じオブジェクトです。コピーされません。 event_container配列はtemp_arrayへのポインタを取得します。もう一度追加すると、同じことになります。 event_containerはポインタの束だけを保持しているので、あなたはそれを検査するときに同じオブジェクトを見ることになります。

それは起こっていることです。これを解決するには、毎月別の配列を作成する必要があります。私はsch's answerがあなたのために働くと思います。

簡単なデモ:行で

NSMutableArray * container = [NSMutableArray array]; 
NSMutableArray * temp = [NSMutableArray array]; 

int i; 
for(i = 0; i < 5; i++){ 
    [temp addObject:[NSNumber numberWithInt:i]]; 
    [container addObject:temp]; // Doesn't copy; just adds pointer to temp 
    [temp removeAllObjects]; 
} 
// Inspecting container now, we find that it has five arrays, all empty. 
NSLog(@"%@", container); 
+0

もし彼がそうしたら、彼は** results.count **のように多くの配列で終わるでしょう。私はこれが彼がしたいことだとは思わない。 – sch

+0

ああ、そうですね。 –

+0

このメソッドを試してみると、ループが通過するたびに新しい配列が作成され、コンテナ配列に新しい配列が追加されるため、最後の結果が得られます –

0

temp_arrayは、ポインタ型です(目的cのすべてのオブジェクトと同様)。そのため、この呼び出しで:

[self.event_container addObject: temp_array];

...そのオブジェクトへのポインタをevent_containerに追加しています。同じオブジェクトに複数のポインタを追加するだけで、新しい配列を作成するわけではありません。あなたが最も可能性の高いやりたいことは、このように、オブジェクトのコピー(へのポインタ)を追加です:

[self.event_container addObject: [temp_array mutableCopy]];

+0

'[temp_array mutableCopy]'を使うと、メモリが漏れています。自分が所有しているオブジェクトへの参照を失っています( '-mutableCopy'の結果)。 – dreamlax

+0

これはARCでは重要ではありませんが、あなたが正しいですが、他の提案された解決策がおそらく良いでしょう。 –

関連する問題