我使用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所建议的那样。
答案 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:
获取卡阵列中卡的相应索引。