2014-04-13 3 views
1

간단한 예로, 다 대다 관계가있는 엔티티가 2 개 있다고 가정 해 보겠습니다. 첫 번째 엔티티는 "Projects"이고 두 번째 엔티티는 두 번째 "Employees"입니다. 프로젝트 엔티티는 1 명 이상의 직원을 가질 수 있으며 직원은 하나 이상의 프로젝트에 참여할 수 있습니다.관계를 사용하는 NSFetchedResultsController 및 테이블

다시 말해서 프로젝트에는 projectName이라는 속성이 있고 withEmployees라는 Employee와 많은 관계가 있습니다. 반대로 Employee는 employeeName과 a와 myProjects라는 프로젝트에 대한 많은 관계를가집니다.

NSFetchedResultsController 사용 projectName을 섹션 이름으로, employeeName을 행에 포함 할 테이블이 필요합니다. 가져온 엔티티로 Project를 사용하면 각 프로젝트를 쉽게 가져 와서 적절한 섹션 이름을 만들 수 있습니다. 그러나 numberOfRowsInSection을 계산할 때 문제가 발생합니다. 가져온 결과가 프로젝트의 레코드 하나를 가져 왔기 때문에 numberofrows는 .withEmployees 관계에있는 NSSet을 조사하지 않으므로 하나의 엔티티 만 보게됩니다. 즉, NSSet 관계 내에서 숫자의 수가 아니라 하나의 직원 만 출력됩니다.

테이블에서 많은 관계를 사용하려면이 문제를 어떻게 극복해야합니까?

감사합니다. 여기

은 fetchedcontroller 코드입니다 :

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Projects" 
    inManagedObjectContext:self.managedObjectContext]; 

[fetchRequest setEntity:entity]; 

NSSortDescriptor *firstSort = [[NSSortDescriptor alloc] initWithKey:@"projectName" 
                     ascending:NO]; 

NSArray *sortDescriptors = @[firstSort]; 

[fetchRequest setSortDescriptors:sortDescriptors]; 


_fetchedController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest 
                    managedObjectContext:self.managedObjectContext 
                     sectionNameKeyPath:@"projectName" 
                       cacheName:nil]; 
+0

fetchedResultsController를 설정하는 데 사용하는 코드를 표시하십시오. –

+0

게시물 하단에 추가되었습니다. 감사. – C6Silver

답변

1

나는 결국 대답을 발견했다. 위에서 설명한 엔티티 관계는 모두 괜찮 았습니다. 이 문제는 to many 관계를 통해 반환 된 올바른 행 수를 다시 얻는 것이 었습니다. 나는 위의 해당 섹션을 사용하고 내가 알 수없는 크기의 세트를 포함하는 하나 개의 행이 항상 있다는 것을 알고 있기 때문에, 나는 하나에 안쪽의 indexpath을 만들어와

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

    Projects *project = [self.fetchedController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:section]]; 

return [project.withEmployees count]; 

} 

: 나는 다음과 같은 방법으로 그 해결 각 섹션에 대해 단 하나의 헤더 레코드 (프로젝트). 그런 다음 관계를 구성하는 NSSet을 살펴보고 단순히 그 수를 반환합니다. 이제 섹션 당 정확한 행 수를 얻습니다. 스스로 세포에 관해서는

: 여기에

Projects *project = [self.fetchedController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:atIndex.section]]; 

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:atIndex]; 

NSArray *empArray = [project.withEmployees allObjects]; 

Employee *employee = [empArray objectAtIndex:atIndex.row]; 

cell.textLabel.text = employee.firstName; 

} 

의 핵심은 하나 개의 섹션 기록을 얻을 후 많은 관계를 구성하는 모든 데이터를 꺼내하는 것이었다. 다시 부모 레코드 만 얻으려면 indexpath를 만들어야합니다. 이제 행을 사용하여 배열을 반복하여 각 요소를 가져올 수 있습니다.

0

방법이 당신이 가져온 결과 컨트롤러의 -initWithFetchRequest:managedObjectContext:sectionNameKeypath:cacheName: 통화에서 올바른 sectionNameKeyPath:을 통과 한 가정

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    id<NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section]; 
    return [sectionInfo numberOfObjects]; 
} 

같은 약.

사이드 노트 : 관계 이름은 일반적으로 속성 또는 속성과 동일한 이름 지정 규칙을 따릅니다. myProjectswithEmployees 대신 projectsemployees을 사용하십시오. 코드가 더 잘 읽히게됩니다 : lawnmower.myEmployees 대신 fred.myProjects, lawnmower.employees 대신 fred.projects이 사용됩니다.

+0

응답 해 주셔서 감사합니다. 당신이 제기하는 문제는 그것이 1 이상을 반환하지 않는다는 것입니다. 행의 수는 NSSet을 조사하고 거기에있는 객체를 계산해야합니다. 결과적으로 하나의 프로젝트 레코드가 발견되어 행 수가 1로 반환됩니다. 실제로 하나의 프로젝트가 있지만 섹션 헤더 프로젝트 이름으로 반환해야하는 직원이 2 명인 NSSet을 포함합니다. 다시 단지 1을 반환한다는 것은 실제로 세트에있는 번호가 아니라 각 프로젝트 아래에 1 명의 직원 만 표시한다는 것을 의미합니다. – C6Silver

+0

위의 추가 텍스트에 대한 응답으로 첫 번째 게시물에 없었습니다. 엔티티는 Projects가 될 것이고 sectionNameKeyPath는 projectName이 될 것입니다 (이것은 내가 찾고있는 섹션 제목이므로). 명명 규칙에 대한 메모를 감사하십시오. 스탠포드 iOS 수업을 들으며 기억해 보면, 그들은 내가 한 일에 더 가까운 이름을 사용했지만 당신의 요점을 말합니다. – C6Silver

+0

각각의'Project' 섹션에 하나의 관련 오브젝트 만 있다면, 그것은 당신의 관계가 제대로 연결되지 않았다는 표시입니다. '-sections'를 호출하면 각 섹션에 대해 하나의'id '인스턴스가 생깁니다. 그것들을 검사하십시오 :'indexTitle','name','numberOfObjects','objects'를보고 의심스러운 것으로 보이는지 확인하십시오. –

0

아직 그래서 위의 코드에 대한 답변 가능한 추가로이 묻는 말씀 드릴 수 없습니다 : 내가 NSSet의 관계의 실체를 검색하고있는 tableview에서 보여 관리

.

그러나 지금 나는 그 tableview에 슬라이드 - 삭제를 구현하려고하고 NSFRC는 관계 배열에서 객체의 삭제를 등록 할 수 없습니다.

이 예제에서 이것은 다음을 의미합니다. Project 개체를 삭제할 수 있지만 Employee 개체를 삭제하면 (0,0) 행이 추가/제거되므로 충돌합니다.

NSArray *empArray = [project.withEmployees allObjects]; 

Employee *employee = [empArray objectAtIndex:atIndex.row]; 

[context deleteObject:employee]; 

당신이 혹시 주위에 일을해야합니까 :

나는 그것을 같은 방식으로 가져오고 그 객체를 삭제 하시겠습니까?

현재 NSFRC에 술어가 없으므로 project.employee를 확인하면 변경 될 수 있습니까? 아니면 Projects를로드하고 섹션을 설정하는 NSFRC와 Employees를로드하고 행을로드하는 NSFRC 2 개를 사용해야합니까? 나는 그들이 삭제 된 객체를 탐지 할 때 여전히 간섭 할 수 있다고 생각한다.

+0

설명에서 전체 데이터베이스의 직원이 아닌 프로젝트에서 직원을 삭제하려고합니다. 후자를 수행하는 것보다 단순히 직원 엔티티를 조회하고 문제의 레코드를 삭제하면 다른 연결된 엔티티의 관계가 업데이트됩니다. 그러나 직원을 그대로두고 프로젝트에서 제거하려면 프로젝트의 ".withEmployees"관계 내에서 NSSet을 업데이트해야합니다. 레코드를 삭제할 수는 없지만 원하는 직원 만 NSSet을 업데이트해야합니다. – C6Silver

+0

감사합니다. 실제로 어떤 식 으로든 업데이트해야했지만 1560 및 1570 코코아 오류가 발생했습니다. 이것은 필자가 필요에 따라 관계를 설정했기 때문에 그것이 관계 개체가 저장 될 때마다 전달되어야한다는 것을 분명히했기 때문입니다 (나는 창조가 충분하면 생각했습니다). 나는 그것을 선택적으로 만들었고 [[myDepartement mutableSetValueForKey : @ "employees"] removeAllObjects]를 사용하여 NSSet을 비울 수있었습니다. 저를 올바른 방향으로 가리켜 주셔서 감사합니다! NSFRC는 관계를 사용할 때 꽤 천적이되고 있습니다 :) – BossBols

관련 문제