코어 데이터를 사용하는 IOS 어플리케이션이 있습니다. 나는 꽤 복잡한 모델 (10 개 이상 엔티티)을 가지고 있으며 모든 것이 잘 작동하고 있습니다 ... 대부분의 경우. 몇 가지 문제점의 근본 원인 또는 문제의 원인이 될 수있는 무엇을 찾아야하는지에 대한 몇 가지 일반적인 지침을 찾아내는 데 도움이 필요합니다.코어 데이터에 데이터/nil 관계가 표시되지 않습니다.
몇 명의 최종 사용자가 문제를 겪고 있습니다. 핵심 데이터와 관련된 두 가지 문제가 있습니다. 그들은 둘 다 단지 (처음 사용 후 시간/일) 잠시 후에 나타나는 것처럼 보입니다.
먼저 JSON을 생성하기 위해 호출 객체 목록을 배열로 가져옵니다. 이 코드는 완벽하게 작동하지만 한두 명의 사용자가 잠시 후에 오류가 발생하기 시작합니다. 호출 엔티티는 callstatus 객체와 관계가 있습니다.이 관계는 statusForCall
이라고합니다. 사용자가이 관계를 nil
으로 설정할 수있는 방법은 없습니다. 관계는 콜 엔티티가 생성 될 때 처음에 명확하게 설정됩니다. 상태는 사용자가 이것을 체크 한 초기 저장 후에 설정되고 행복하다). 그러나 모든 호출 객체 statusForCall
이 1 회 호출하면 nil
이 반환됩니다.
위로 가기 위로 응용 프로그램을 설치하면이 문제가 해결 될 것으로 보입니다 (데이터가 변경되지 않지만 관계가 다시 작동 함).
두 번째 문제는 약간 다릅니다. 테이블 뷰에 대해 NSFetchedResultsController
을 통해 호출 개체 목록을 가져옵니다. 이것은 간단한 필터가 적용됩니다. 표보기가 비어 있습니다. 원래 필터와 추가 필터를 적용하면 데이터가 반환됩니다. 초기 필터는 closedDate
이 아니며 nil
이 아닙니다. 일치하는 레코드가 있더라도 테이블 뷰를 비워 둡니다. 필터를 closedDate
으로 변경하면 nil
이 아니며 scheduledDate
이 아닌 것은 nil
이 아니며 필터가 원본과 동일하지만 ADDED 조건이 있다고 생각되는 경우에도 tableview에 데이터를 반환합니다.
다시이 문제는 몇 명의 사용자에게만 발생합니다. 곧바로 일어나는 일이 아니며 시작하는 데 몇 시간에서 며칠이 걸릴 수 있습니다.
이상하게도 tableview 문제는 잠시 후 다시 해결 될 것으로 보입니다.
나는이 동작이 캐시에 의해 우연히 될 수 있지만 가져 오기 요청에 대한 cachename으로 nil
을 지정했습니다.
나는 데이터가 정확하다는 것을 99 % 확신한다는 사실을 이해하지 못한다.
stausForCall
의 첫 번째 문제는 nil
입니다. 관계 속성에 액세스 할 때까지는 CD가 데이터를 제공하지 않을 수도 있음을 이해합니다.하지만이 작업을 수행하고 있습니다. 오류가있는 행은 다음과 같습니다.
[dict setObject:aCall.statsuForCall.statusID forKey:@"statusID"];
그래서 속성에 액세스하고 있습니다.
이 관계는 사용자가 nil
으로 설정할 수 없으며 호출 객체가 처음 생성되면 관계를 변경하는 코드가 없습니다.
사실 일정 시간이 지나야 만 발생한다는 사실 또한 나를 혼란스럽게합니다.
다시 데이터를 제공하지 않는 테이블 뷰는 조금 임의적입니다. 이것은 CD의 다른 객체에 액세스하는 2 개의 다른 뷰 컨트롤러에서도 발생했습니다.코드 나 응용 프로그램을 변경하지 않고 사용자가 몇 시간 후에 다시 작업을 시작했거나 작동하지 않는다고보고했습니다.
CD 저장소가 손상 될 수 있습니까? 캐싱 문제일까요? 내재 된 데이터가 실제로 괜찮은지 어떻게 테스트 할 수 있습니까?
가장 큰 문제는 사용자가 문제를 신고 할 때입니다. 빌드에 디버그 코드를 추가하고 애플리케이션을 덮어 쓰게되면 즉시 문제가 사라집니다. 코드 및 데이터가 변경되지 않습니다. 일부 디버그 경고를 추가했습니다.
핵심 데이터로 인해 데이터가 마이그레이션되고 모든 문제가 "수정 된"것이므로이 역시 마찬가지입니다. 행복은 사용자를위한 2 개 선택과 액션 버튼이 있습니다 - - 작품 "채용 정보"를 페치 요청
코드를 (당신은 아마! 말할 수있는)
내가이에 의해 매우 혼란 스러워요 99.999999 %의 시간이지만 정의되지 않은 시간이 지난 후 사용자에 대해 중지됩니다. 이 첫 번째 필터가 작동하지 않으면 두 번째 필터가 여전히 작동합니다.
[self changeTitle];
NSFetchRequest *request=[NSFetchRequest fetchRequestWithEntityName:@"Call"];
NSString *sectionKeyPathName=nil;
NSString *searchPre=self.searchBar.text;
// self.showIndex = YES;
if ([self.mode isEqualToString:@"OPEN JOBS"])
{
request.predicate = [NSPredicate predicateWithFormat:@" closedDate = nil and assignedToCall==YES"];
if ([self.searchBar.text length]>0)
{
NSPredicate * newCondition = [NSPredicate predicateWithFormat:@"(shortAddress CONTAINS[cd] %@ or address CONTAINS[cd] %@ or lettingArea CONTAINS[cd] %@ or postCode CONTAINS[cd] %@ or woRef CONTAINS[cd] %@)",searchPre,searchPre,searchPre,searchPre,searchPre];
NSPredicate * newPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:request.predicate, newCondition, nil]];
request.predicate = newPredicate;
}
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"hasAppointmentForOrderBy" ascending:NO ];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"dateScheduled" ascending:YES ];
NSSortDescriptor *sortDescriptor3 = [[NSSortDescriptor alloc] initWithKey:@"scheduledTime" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *sortDescriptor4 = [[NSSortDescriptor alloc] initWithKey:@"dateDue" ascending:YES ];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,sortDescriptor2,sortDescriptor3,sortDescriptor4, nil];
[request setSortDescriptors:sortDescriptors];
[email protected]"sectionHeaderSortScheduledOrNot";
}
if ([self.mode isEqualToString:@"TODAY'S JOBS (ONLY)"])
{
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
NSDate* todayNoTime = [[NSCalendar currentCalendar] dateFromComponents:comps];
request.predicate = [NSPredicate predicateWithFormat:@"(dateDue = %@ or dateScheduled = %@) and closedDate = nil and assignedToCall==YES",todayNoTime,todayNoTime];
if ([self.searchBar.text length]>0)
{
NSPredicate * newCondition = [NSPredicate predicateWithFormat:@"(shortAddress CONTAINS[cd] %@ or address CONTAINS[cd] %@ or lettingArea CONTAINS[cd] %@ or postCode CONTAINS[cd] %@ or woRef CONTAINS[cd] %@)",searchPre,searchPre,searchPre,searchPre,searchPre];
NSPredicate * newPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:request.predicate, newCondition, nil]];
request.predicate = newPredicate;
}
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"shortAddress" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[email protected]"lettingArea";
}
self.currentFilter= request.predicate;
[self.managedObjectContext performBlockAndWait:^{
self.fetchedResultsController =[[NSFetchedResultsController alloc ] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:sectionKeyPathName cacheName:nil];
}];
안녕 - 모든 가져 오기 요청 캐시 이름이 이미 nil로 설정되어 있습니다. –
OP –