Objective-C - 在特定索引处将对象添加到NSMutableArray

时间:2015-03-04 20:51:15

标签: ios objective-c asynchronous nsmutablearray

我使用Parse作为我的后端。保存/获取对象在与主线程分开的线程中运行,因此如果您对要尝试获取的数据执行任何操作,则必须在后台块中执行此操作,如下所示:

[Card fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    ...
    //setting up button based on Card's name
    ...
    [buttonArray addObject:button];
}];

这将创建一个新线程,并且当从Parse获取对象时,块中的代码将运行。

我从附加到解析用户的卡片组中为每个Card对象添加一个按钮。当您按下卡片按钮时,您可以看到有关它的一些信息,并选择删除它。我执行一个展开segue,它处理删除已删除卡片的按钮以及移除已删除卡片下方的任何按钮,因此没有间隙。我的问题是,由于按钮是在另一个线程内创建并添加到我的数组中的,因此某些对象设法无序地获取。所以我的屏幕可能会显示按顺序为1 2 3 4的按钮,但是我的数组还有按钮[3,2,1,4]。如何确保我按照它们在屏幕上显示的顺序保持数组中的按钮,这与存储在Parse数组中的卡的顺序相同?

以下是我如何删除当前正在移动错误按钮的按钮:

-(IBAction)prepareForUnwindPaymentCardDeleted:(UIStoryboardSegue *)segue
{
    [buttonArray removeObjectAtIndex:cardNum];
    for( int i = cardNum; i < [buttonArray count]; i++)
    {
        UIButton *button = [buttonArray objectAtIndex:i];
        [button setTag:i];
        [button setFrame:CGRectMake(xCenter-width/2, button.frame.origin.y - 52, width, height )];
    }
    yValue -= 52;
}

yValue是按钮原点的y坐标,如果我添加新的卡/按钮,则对应于下一个按钮应放置的y坐标。因此,当我删除一个按钮/卡时,我减少了yValue,所以我不会在当前的最后一个按钮和一个新按钮之间留下间隙。 cardNum是一个变量,它等于我的Parse数组中卡的索引,也是按钮出现顺序的索引。但是,我发现它并不总是buttonArray中按钮的索引。

我想要的是我的NSMutableArray buttonArray使其索引对应于按钮在屏幕上显示的顺序,所以如果我删除按钮3,我必须向上移动按钮4-n以填补间隙,然后减少他们的每个标签都对应正确的卡片。

编辑 - 我的解决方案最终只是创建按钮并在fetchinbackground调用之前将其添加到我的数组中。这样,一切都按照我预期的顺序添加。我不正确地使用了insertObjectAtIndex方法,但由于我添加的索引等于count,所以它没有抛出任何错误。当我更多地了解它们时,我会使用NSMutableDictionary,正如Josh和Duncan所建议的那样。

3 个答案:

答案 0 :(得分:2)

更改您的设计,不要使用数组作为按钮。你正试图破解解决问题的方法。你有一组对象,按钮,每个对象都需要与另一组对象之一相关联。这是一个映射,因此请使用映射集合:NSMutableDictionary

或者,但不太理想,因为它混合了MVC分离,为你的Card类型添加了一个按钮属性,并让每张卡保持一个(理想上很弱)指向其相关按钮的指针。

答案 1 :(得分:2)

NSArrays中不能包含空位,因此不能使用insertObject:atIndex:将元素插入到数组末尾。

我相信你可以用它来添加一个元素:

NSMutableArray *array = [NSMutableArray arrayWithCapcity: 10];
int index = 0;

[array insertObject @"foo" atIndex: index++];

甚至

array[index++] = @"foo";

正如Josh所指出的,如果你想从按钮映射到对象,请使用字典。

如果你真的想要一个“稀疏”数组,那么可以用NSNull对象填充空格,然后使用replaceObjectAtIndex:withObject:

这样的事情:

int count = 10;
NSMutableArray *array = [NSMutableArray arrayWithCapcity: count];
int index = 0;
for (int index = 0; index<count; index++);
   array[index] = [NSNull null];

然后替换一个对象(例如在索引7处):

[array replaceObjectAtIndex: 7 withObject @"foo"];

array[7] = @"foo";

NSNull对象用于此特定目的。对于像数组这样的集合,它们本质上是一个“故意留空的页面”对象。然后,您可以使用

之类的测试代码
if (array[7] == [NSNull null)
  array[7] = @"foo";

...根据数组中的“空”位置做出决策。 (在极少数情况下,您可以使用==来比较对象的相等性,因为只有一个NSNull对象。它是一个单例。)

答案 2 :(得分:-1)

您是否在insertObject:atIndex:中尝试了NSMutableArray方法?您可以使用indexOfObject:获取卡阵列中卡的相应索引。