从循环中将 NSMutableArray 添加到另一个似乎会创建重复项

发布于 2025-01-06 12:12:50 字数 2505 浏览 4 评论 0原文

我正在解析 json 编码事件的 NSDictionary ,并根据月份将它们放入二维 NSMutableArray 中,以便在分段表视图中显示。

由于我将项目添加到数组中,然后将该数组放入循环中的数组 (event_container) 中,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;

I'm parsing through an NSDictionary of json-encoded events and placing them into a two-dimensional NSMutableArray based on their month -- for display in a sectioned table view.

Since I am adding items to an array and then placing that array in an array (event_container) in a loop, event_container shows the correct number of arrays, however, they all appear to be duplicates of the last iteration, so all of the contents of event_container are the same array.

I believe this is because it's a pointer and/or not being released. I'm unsure of an appropriate way around this or possibly even a better solution. I'm using 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++;

}

Those arrays are declared as properties:

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

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

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

发布评论

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

评论(3

时光沙漏 2025-01-13 12:12:50

在该行中:

[self.event_container addObject: temp_array];

您始终将相同的实例 temp_array 添加到 self.event_container 中。这就是为什么您会看到同一个数组重复多次。

您可以通过执行以下操作来解决此问题,例如:

- 在 for 循环之前添加以下内容

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

- 删除

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

- 并将其后的代码更改为:

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

In the line:

[self.event_container addObject: temp_array];

You are always adding the same instance temp_array to self.event_container. This is why you see the same array duplicated many times.

You can solve this by doing the following for example:

-Add the following before your for loop

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];
}

-and change the code that comes after that into :

tmp_array = [event_container objectAtIndex:month];
[temp_array addObject:anEvent];
拥抱没勇气 2025-01-13 12:12:50

您对数组是指针的怀疑基本上是正确的。问题是您的 temp_array 并不是那么临时——实际上每次循环时它都是同一个数组对象。

您在循环外部创建它,每当您发送 addObject:removeAllObjects 时,它都会影响您已放入其中的内容。

但关键在于,当您将 temp_array 添加到 event_container 时,它是完全相同的对象。它不是被复制的; event_container 数组仅获取指向 temp_array 的指针。当你再次添加它时,它是一样的。由于 event_container 仅保存一大堆指针,因此当您检查它时,您最终会看到同一个对象。

这就是正在发生的事情。为了解决这个问题,您需要为每个月创建一个单独的数组;我认为sch的答案对你有用。

快速演示:

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

Your suspicions about the array being a pointer is basically correct. The problem is that your temp_array isn't so temporary -- it's in fact the same array object every time through your loop.

You're creating it outside the loop, and whenever you send it addObject: or removeAllObjects, it's affecting the stuff that you've already put in there.

The key part, though, is that when you add the temp_array to event_container, it's the exact same object. It's not copied; the event_container array just gets a pointer to temp_array. When you add it again, it's the same thing. Since event_container just holds a whole bunch of pointers, you end up looking at the same object when you inspect it.

That's what's happening. To solve this, you need to create a separate array for each month; I think that sch's answer will work for you.

A quick demonstration:

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);
素食主义者 2025-01-13 12:12:50

temp_array 是一个指针类型(与 Objective c 中的所有对象一样)。因此,通过此调用:

[self.event_container addObject: temp_array];

...您将指向该对象的指针添加到 event_container。您不是在创建新数组,而只是向同一个对象添加多个指针。您最可能想要做的是添加对象的(指向)副本,如下所示:

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

temp_array is a pointer type (like all objects in objective c). Therefore, with this call:

[self.event_container addObject: temp_array];

...you are adding a pointer to that object to event_container. You are not creating a new array, merely adding multiple pointers to the same object. What you most likely want to do is add a (pointer to a) copy of the object, like this:

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

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