Iphone KVC集合存取器+;索引0超出空数组错误的界限

Iphone KVC集合存取器+;索引0超出空数组错误的界限,iphone,ios,cocoa-touch,key-value-observing,key-value-coding,Iphone,Ios,Cocoa Touch,Key Value Observing,Key Value Coding,我声明并合成了一个可变数组属性: @property (nonatomic, strong) NSMutableArray *arrayOfTasks; 我正在为相同的属性使用,并且我还有其他方法,这些方法将在内部调用此KVC集合访问器方法,如下所示: -(void)insertObject:(CSTaskAbstract *)inTask inArrayOfTasksAtIndex:(NSUInteger)index { [[self arrayOfTasks] insert

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

@property (nonatomic, strong) NSMutableArray *arrayOfTasks;
我正在为相同的属性使用,并且我还有其他方法,这些方法将在内部调用此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 accessor方法中包括以下内容:

-(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
条件返回布尔否,应用程序就会崩溃,根本没有堆栈跟踪!(堆栈跟踪位于应用程序的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]];
    }
}
我可以继续使用这种方法,这种方法是有效的,不会崩溃,但我担心的是:

  • 如果其他程序员希望从其他地方调用指定的方法,那么在将来添加相同的签入指定方法将是一个额外的优势

  • 为什么应用程序会在第一种情况下崩溃,因为我不会根据某些条件检查将对象插入KVC集合访问器中的数组

  • 谢谢你的意见


    Raj

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

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

    您发布的第二个代码被截断,在不需要插入时不调用KVC集合访问器,从而避免了此错误


    如果您想尽量减少有人错误使用这些方法的可能性,只需在公共头中公开
    -addobjectinarrayoftask:
    。此外,您还可以对此进行记录。如果您想绝对确定int本身无法访问
    -insertObject:inandex:
    ,可以添加一个
    NSAssert
    ,检查该方法是否是从
    -addobjectinarayofttask:

    调用的。是的,我认为您对KVC的介绍是有意义的。我很好奇如何基于您提到的方法的调用方进行断言,您能给我解释一下吗?一种方法是在调用
    -addobjectinarayoftasks:
    之前定义一个BOOL实例变量并将其设置为YES。在后面的示例中,您将使用断言检查值是否已设置,然后将其重置为否。如果您是从多个线程调用此函数,则还需要对正在设置的标志和重置之间的代码段进行某种同步。明白了,是的,这是可能的。接受你的答案,因为我相信你的思维过程:)