KVC Collection Accessor +索引0超出空数组错误的界限

时间:2012-11-09 07:04:59

标签: iphone ios cocoa-touch key-value-observing key-value-coding

我声明并合成了一个可变数组属性:

@property (nonatomic, strong) NSMutableArray *arrayOfTasks;

我正在使用KVC collection Accessors作为同一个属性,我还有其他方法会在内部调用这个KVC Collection访问器方法,如下所示:

-(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index
{
        [[self arrayOfTasks] insertObject:inTask
                                  atIndex:index];
}
-(void)addObjectInArrayOfTasks:(CSTaskAbstract *)inTask
{
        [self insertObject:inTask
     inArrayOfTasksAtIndex:[[self arrayOfTasks] count]];
}

我必须做一些修改,并且只在满足特定条件时才将对象添加到数组中,因此为了确保此检查进入指定方法,我在-insertObject KVC Collection访问器方法中包含以下内容:

-(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index
{
    if ([inTask isOperatable])
    {
        [[self arrayOfTasks] insertObject:inTask
                                  atIndex:index];
    }
}
-(void)addObjectInArrayOfTasks:(CSTaskAbstract *)inTask
{
        [self insertObject:inTask
     inArrayOfTasksAtIndex:[[self arrayOfTasks] count]];
}

现在,每当我触发-addObjectINArrayOfTasks方法并且-isOperatable条件返回布尔值NO时,应用程序崩溃时根本没有堆栈跟踪! (堆栈跟踪位于应用程序的main())。它只是“索引0超出空数组错误的界限”

我不明白这个的原因,我还没有尝试访问数组,所以我没有给框架机会抱怨我在索引0处没有元素。此外,我正在计算在从数组中访问对象之前,数组项检查到处。因为,如果我试图访问和元素超出边界索引,应用程序将在同一点崩溃,让我知道我试图访问索引越界的确切位置。这本来是一个简单明了的解决办法。

现在,为了交叉验证,我对代码进行了一些小改动,这似乎有效:

-(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index
{
        [[self arrayOfTasks] insertObject:inTask
                                  atIndex:index];
}
-(void)addObjectInArrayOfTasks:(CSTaskAbstract *)inTask
{
    if ([inTask isOperatable])
    {
        [self insertObject:inTask
     inArrayOfTasksAtIndex:[[self arrayOfTasks] count]];
    }
}

我可以继续使用这种方法,这种方法有效并且不会崩溃,但我的担忧如下:

  1. 如果其他程序员想要从其他地方调用指定的方法,将来在指定方法中添加相同的检查将是一个额外的优势。

  2. 当我不根据某些条件检查将对象插入KVC集合访问器中的数组时,为什么应用程序会崩溃?

  3. 感谢您提供任何意见,

    拉​​吉

1 个答案:

答案 0 :(得分:2)

我认为您看到的崩溃更可能与内部KVC行为相关,而不是您的阵列。这可能是您没有看到可用堆栈跟踪的原因。你在Xcode中启用了异常断点吗?

KVC基本上期望-insertObject:in<Key>AtIndex:将在给定索引处插入新对象(在您的情况下可能为0)。由于它假定插入了对象,因此现在可以通过对给定索引处的对象排队数据结构(NSMutableArray)来访问它。当条件演变为NO时,您无法插入此对象,这意味着当KVO尝试使用提供的索引进行查询时,可能会出现索引超出范围的异常。

您发布的第二个代码通过在不需要插入时不调用KVC集合访问器来避免此错误。

如果您希望尽量减少错误使用这些方法的可能性,请在公共标题中公开-addObjectInArrayOfTasks:。此外,您可以记录这一点。如果您想确保无法在int上自己访问-insertObject:in<Key>AtIndex:,可以添加NSAssert,检查该方法是否来自-addObjectInArrayOfTasks: