2014-06-12 4 views
0

У меня проблема, которую я не могу решить. Im создает приложение iOS с базой данных Core. Все шло отлично, пока я не получил исключение NSRangeException. Это исключение я получаю в функции, которая проверяет, нужно ли обновлять данные приложения.Основные данные IOS NSRangeException

Мой код:

- (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) 

Ребята, кто может мне помочь, пожалуйста? Я действительно нуждаюсь в вашей помощи. Спасибо.

+0

Нажмите галочку под подсчетом голосов, чтобы принять его, не добавляйте «разрешено» в заголовок. – nicael

ответ

2

Вашего смутьян, кажется, be

NSManagedObject * changesGrabbed = [результаты объектаAtIndex: 0];

Если результаты является пустой массив, вызов objectAtIndex: 0 вызовет NSRangeException, потому что нет объекта с индексом 0. Лучше вызов [Результаты firstObject], который не врезаться с ошибкой, если результатом является пустой массив. firstObject() просто возвращает нуль в этом случае.

+0

Большое спасибо! –

+0

Постарайтесь следить, поскольку вы будете отправлять сообщения в нуль, что вызовет проблемы дальше по прямой, если не будет явной проверки существования объекта перед отправкой его сообщений. – Justin

+0

Но можете ли вы сказать мне, почему это ошибка может быть пустой? Может случиться, что я пытаюсь достичь пустой базы данных? –

1

Вы пытаетесь получить объект из пустого массива. Сначала вы должны проверить, содержит ли массив какие-либо объекты. Используйте count свойство:

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

Большое спасибо! –

+2

Вы отредактировали свой вопрос со словом «Solved» в названии, но вы не ответили как принято. Вы должны сделать это, чтобы тот, кто правильно ответил вам, получил уведомление и бонус за репутацию. – Justin

+0

Извините, Im новый здесь :). –

1

Просто перед

NSManagedObject* changesGrabbed = [results objectAtIndex:0]; 

Добавить ветку на основе возвращаемых результатов. Что-то вроде следующего:

if (results && [results count] > 0) { 
    NSManagedObject* changesGrabbed = [results objectAtIndex:0]; 
    ... 
} 

Ваш массив пуст. StackTrace в значительной степени выговаривать это для вас -

причины: '* - [__ NSArrayI objectAtIndex]: индекс 0 за пределы для
пустого массива'

+0

Спасибо вам большое! –

+2

Нет необходимости дважды проверять результаты; 'if ([count count]> 0) ...' будет достаточно. – jlehr

+0

Мой пример был немного педантичным, да. Однако, я полагаю, это экономит затраты на отправку сообщений, вызов метода и сравнение (за счет первоначального сравнения). – greymouser

Смежные вопросы