0

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

@property (nonatomic, strong) NSMutableArray *arrayOfTasks;

我将KVC 集合访问器用于相同的属性,并且我还有其他方法将在内部调用此 KVC 集合访问器方法,如下所示:

-(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 集合访问器中的数组时,为什么应用程序会在第一种情况下崩溃?

感谢您的任何投入,

拉吉

4

1 回答 1

2

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

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

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

如果您想最大程度地减少某人错误地使用这些方法的机会,请仅-addObjectInArrayOfTasks:在您的公共标头中公开。此外,您可以记录这一点。如果您想绝对确定-insertObject:in<Key>AtIndex:不能在 int 上访问,您可以添加一个NSAssert, 来检查该方法是否是从 调用的-addObjectInArrayOfTasks:

于 2012-11-09T07:47:56.077 回答