2014-06-12 3 views
0

해결할 수없는 문제가 있습니다. 코어 데이터 프레임 워크를 사용하여 iOS 응용 프로그램을 만드는 중입니다. 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 = [results objectAtIndex : 0];

결과가 objectAtIndex 전화는 하늘의 배열 인 경우 : 0 NSRangeException의 원인이됩니다이 때문에 인덱스 0에서 더 객체가없는 당신은 더 나은 호출 [결과 firstObject, 충돌하지 것이다는 결과가 빈 배열 인 경우 오류가 발생합니다. firstObject()는이 경우 nil을 반환합니다.

+0

대단히 감사합니다! –

+0

메시지를 보내기 전에 객체가 있는지 여부를 명시 적으로 확인하지 않으면 문제가 줄 서게 될 메시지를 nil에 보낼 것이므로주의해야합니다. – Justin

+0

하지만 왜 이렇게 할 수 있습니까? 오류가 비어있을 수 있습니까? 임 빈 데이터베이스에 도달하려고하기 때문에 일어날 수 있습니까? –

1

빈 배열에서 개체를 검색하려고 시도하고 있습니다. 배열에 객체가 있는지 먼저 확인해야합니다. 반환 된 결과에 따라 분기를 추가

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

죄송합니다, 임 새로운 여기 :). –

1

그냥

NSManagedObject* changesGrabbed = [results objectAtIndex:0]; 

전에 다음 count 속성을 사용합니다. 다음과 같은 것 :

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

배열이 비어 있습니다. 스택 트레이스는 꽤 많이 당신을 위해 그것을 주문 -

이유 : '은 *이 - [__ NSArrayI objectAtIndex이 :] :
빈 배열의 범위를 넘는 인덱스 0'

+0

대단히 감사합니다! –

+2

'results'를 두 번 확인할 필요가 없습니다. 'if ([결과 개수]> 0) ... '이면 충분합니다. – jlehr

+0

나의 예는 좀 현저하다. 그러나 메시지 디스패치, 메서드 호출 및 비교 비용을 절약한다고 가정합니다 (초기 비교 비용). – greymouser

관련 문제