iOS核心数据异常

iOS核心数据异常,ios,json,core-data,nsrangeexception,Ios,Json,Core Data,Nsrangeexception,我有一个无法解决的问题。我正在使用核心数据框架创建一个iOS应用程序。一切都很顺利,直到我得到一个例外。我在函数中得到的这个异常检查应用程序数据是否需要更新 我的代码是: - (BOOL) isTimetableUpdatedWithJSONData:(NSMutableDictionary*) data { appDelegate = [[UIApplication sharedApplication] delegate]; managedObjectContext = [ap

我有一个无法解决的问题。我正在使用核心数据框架创建一个iOS应用程序。一切都很顺利,直到我得到一个例外。我在函数中得到的这个异常检查应用程序数据是否需要更新

我的代码是:

- (BOOL) isTimetableUpdatedWithJSONData:(NSMutableDictionary*) data
{
    appDelegate = [[UIApplication sharedApplication] delegate];
    managedObjectContext = [appDelegate managedObjectContext];

    //Do database update check logic here
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:[NSEntityDescription entityForName:@"MobileTimetableDataHash"     inManagedObjectContext:managedObjectContext]];

    NSError *error = nil;
    NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];

    if (error != nil)
    {
        [self printErrorAlert];
    }
    //THERE IS ERROR HERE
    NSManagedObject* changesGrabbed = [results objectAtIndex:0];
    NSString *changesFromDatabase = [changesGrabbed valueForKey:@"changes"];
    NSString *changesFromService = [data valueForKeyPath:@"changes"];

    if ([changesFromService isEqualToString:changesFromDatabase])
    {
        return YES;
    }
    else
    {
        [changesGrabbed setValue:changesFromService forKey:@"changes"];

        [managedObjectContext save:&error];

        if (error != nil)
        {
            [self printErrorAlert];
        }
        return NO;
    }

}
例外情况:

2014-06-12 21:36:12.034 MIF[437:60b] *** Terminating app due to uncaught exception     'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for     empty array'
*** First throw call stack:
(
0   CoreFoundation                      0x0000000101cb3495 __exceptionPreprocess +     165
1   libobjc.A.dylib                     0x0000000101a1299e objc_exception_throw + 43
2   CoreFoundation                      0x0000000101c6be3f -[__NSArrayI     objectAtIndex:] + 175
3   MIF                                 0x0000000100001942 -[MIFTimetableService     isTimetableUpdatedWithJSONData:] + 514
4   MIF                                 0x000000010000219d -[MIFAppDelegate     synchrinizeTimetableService] + 157
5   MIF                                 0x0000000100001dc2 -[MIFAppDelegate     application:didFinishLaunchingWithOptions:] + 114
6   UIKit                               0x00000001005ba3d9 -[UIApplication     _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 264
7   UIKit                               0x00000001005babe1 -[UIApplication     _callInitializationDelegatesForURL:payload:suspended:] + 1605
8   UIKit                               0x00000001005bea0c -[UIApplication     _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
9   UIKit                               0x00000001005cfd4c -[UIApplication     handleEvent:withNewEvent:] + 3189
10  UIKit                               0x00000001005d0216 -[UIApplication     sendEvent:] + 79
11  UIKit                               0x00000001005c0086 _UIApplicationHandleEvent     + 578
12  GraphicsServices                    0x0000000103ce671a _PurpleEventCallback +     762
13  GraphicsServices                    0x0000000103ce61e1 PurpleEventCallback + 35
14  CoreFoundation                      0x0000000101c35679     __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
15  CoreFoundation                      0x0000000101c3544e __CFRunLoopDoSource1 +    478
16  CoreFoundation                      0x0000000101c5e903 __CFRunLoopRun + 1939
17  CoreFoundation                      0x0000000101c5dd83 CFRunLoopRunSpecific +     467
18  UIKit                               0x00000001005be2e1 -[UIApplication _run] +     609
19  UIKit                               0x00000001005bfe33 UIApplicationMain + 1010
20  MIF                                 0x0000000100001d23 main + 115
21  libdyld.dylib                       0x000000010234b5fd start + 1
22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

伙计们,有人能帮我吗?我真的需要你的帮助。谢谢。

您正在尝试从空数组中检索对象。您应该首先检查数组是否包含任何对象。使用
count
属性:

if (results.count > 0) {
    NSManagedObject* changesGrabbed = [results objectAtIndex:0];
    //continue...
} else {
    //Array is empty, object 0 will be beyond bounds
}

您正试图从空数组中检索对象。您应该首先检查数组是否包含任何对象。使用
count
属性:

if (results.count > 0) {
    NSManagedObject* changesGrabbed = [results objectAtIndex:0];
    //continue...
} else {
    //Array is empty, object 0 will be beyond bounds
}
就在之前

NSManagedObject* changesGrabbed = [results objectAtIndex:0];
根据返回的结果添加分支。如下所示:

if (results && [results count] > 0) {
    NSManagedObject* changesGrabbed = [results objectAtIndex:0];
    ...
}
你的数组是空的。stacktrace几乎为您解释清楚了--

原因:'*-[\uu NSArrayI objectAtIndex:]:索引0超出了
空数组'

就在之前

NSManagedObject* changesGrabbed = [results objectAtIndex:0];
根据返回的结果添加分支。如下所示:

if (results && [results count] > 0) {
    NSManagedObject* changesGrabbed = [results objectAtIndex:0];
    ...
}
你的数组是空的。stacktrace几乎为您解释清楚了--

原因:'*-[\uu NSArrayI objectAtIndex:]:索引0超出了
空数组'


你的麻烦制造者似乎是

NSManagedObject*changesGrabbed=[结果对象索引:0]


如果结果是空数组,则调用objectAtIndex:0将导致NSRangeException,因为索引0处没有对象。您最好调用[results firstObject],如果结果为空数组,它不会因错误而崩溃。firstObject()在这种情况下只返回nil。

您的麻烦制造者似乎

NSManagedObject*changesGrabbed=[结果对象索引:0]


如果结果是空数组,则调用objectAtIndex:0将导致NSRangeException,因为索引0处没有对象。您最好调用[results firstObject],如果结果为空数组,它不会因错误而崩溃。firstObject()在这种情况下只返回nil。

但是需要注意,因为您将向nil发送消息,这将导致后续问题,除非在发送消息之前明确检查对象是否存在。但是,您能告诉我,为什么此错误可能为空吗?这可能是因为我试图访问空数据库吗?可能是因为您正在执行的NSFetchRequest没有返回任何匹配的对象。我想这是意料之中的行为。您正在检查是否存在错误(!=nil),但只有在执行请求时出现实际问题时才会返回此错误,而在没有结果时不会发现此错误问题是我在开始时尝试使用测试数据更新数据库。我的函数用于查找测试数据并进行更新。当我将应用程序移动到另一个Mac时,并没有要更新的测试数据,应用程序崩溃。谢谢你们!但是需要注意的是,由于您将向nil发送消息,这将导致后续问题,除非在发送消息之前明确检查对象是否存在。但是,您能否告诉我,为什么此错误可能为空?这可能是因为我试图访问空数据库吗?可能是因为您正在执行的NSFetchRequest没有返回任何匹配的对象。我想这是意料之中的行为。您正在检查是否存在错误(!=nil),但只有在执行请求时出现实际问题时才会返回此错误,而在没有结果时不会发现此错误问题是我在开始时尝试使用测试数据更新数据库。我的函数用于查找测试数据并进行更新。当我将应用程序移动到另一个Mac时,并没有要更新的测试数据,应用程序崩溃。谢谢你们!无需检查
结果
两次<代码>如果([results count]>0).就足够了。我的例子有点迂腐,是的。但是,我认为它节省了消息分派、方法调用和比较的成本(以初始比较为代价)<代码>如果([results count]>0).就足够了。我的例子有点迂腐,是的。但是,我认为这样做可以节省消息发送、方法调用和比较的成本(以初始比较为代价)。您在标题中用“已解决”一词编辑了问题,但没有将答案检查为已接受。你应该这样做,以便正确回答你的人得到通知并获得声誉奖励。对不起,我是新来的:)。你在标题中用“已解决”一词编辑了你的问题,但你没有将答案检查为已接受。您应该这样做,以便正确回答您的人得到通知并获得声誉奖金。对不起,我是新来的:)。点击答案计票下方的复选标记,使其被接受,不要在标题中添加“已解决”。点击答案计票下方的复选标记,使其被接受,不要在标题中添加“已解决”。