2012-04-09 11 views
2

私は、人々が出版物をいつ受け取ったかを把握しているアプリで遊んでいます。 私は2つのコアデータエンティティ(パブリケーションと人物)を持っています。これらのエンティティは、互いに多くの関係を持っていて、互いに多くの関係を持っています。 出版物< < - >>人。iOSコアデータの関係を繰り返します。

人が出版を受け取った場合、セルがスタイルチェックマークである必要があるように、関係を反復しようとしています。彼らがしていない場合は、セルスタイルの平野でなければなりません。ここで私はこれまで持っているものです。

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { 

    Person *personForCell = (Person *) [fetchedResultsController objectAtIndexPath:indexPath]; 
    cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", personForCell.firstName, personForCell.lastName]; 


    NSArray *issuesForPersonArray = [personForCell.issues allObjects]; 

    if ([issuesForPersonArray count] != 0) { 

    for (int i = 0; i <= [issuesForPersonArray count]; i++) { 
     if ([issuesForPersonArray objectAtIndex:i] == km) { 
      cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     }else { 
      cell.accessoryType = UITableViewCellAccessoryNone; 
     } 
    } 
} 

私はこれを実行すると、それは限りどれもが本出版物との関係を持っていないとして、すべての人が表示されます。私は自分の名前を選択したら、しかし、私はこのログを取得:

がキャッチされない例外により 'NSRangeException'、理由にアプリを終了: '*- [__ NSArrayI objectAtIndex:]:範囲外のインデックス1 [0 .. 0ここで」

はdidSelectRow方法である:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:NO]; 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    if (cell.accessoryType == UITableViewCellAccessoryNone) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     // Reflect selection in data model 
     Person *personSelected = (Person *) [fetchedResultsController objectAtIndexPath:indexPath]; 
     [publication addPersonObject:personSelected]; 


    } else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
     // Reflect deselection in data model 
     Person *personSelected = (Person *) [fetchedResultsController objectAtIndexPath:indexPath]; 
     [publication removePersonObject:personSelected]; 

    } 

} 

私はこのすべて間違っについてつもりだと確信している、任意の助けをいただければ幸いです。

これがわかりました。ここで私はあなたのコードの基本的な設計上の欠陥があり

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { 

    Person *personForCell = (Publisher *) [fetchedResultsController objectAtIndexPath:indexPath]; 
    cell.textLabel.text = [NSString stringWithFormat:@"%@ %@", personForCell.firstName, personForCell.lastName]; 

    NSMutableArray *issuesForPersonArray = [[personForCell.publication allObjects] mutableCopy]; 

    if ([issuesForPersonArray count] != 0) { 

     for (Publication *publicationForPerson in issuesForPersonArray) { 
      if (publicationForPerson == publication) { 
       cell.accessoryType = UITableViewCellAccessoryCheckmark; 
      }else { 
       cell.accessoryType = UITableViewCellAccessoryNone; 
      } 
     } 
    } 
} 

答えて

1

を使用したものです。 UI要素(チェックマーク)を使用してデータモデルを通知しています。これは非常にエラーが発生しやすく、MVC(Model-View-Controller)プログラミングパラダイムのすべてのルールを破ります。

チェックマークを表示する基本的な方法はokです。使用するUI要素を決定するために、データモデルを調べます。ただし、索引でオブジェクトをループするのは最良の方法ではありません。また、テーブルビューをスクロールするとループが非常に高価になります。ここでは別のアプローチがある:

(。私はkmが問題の出版エンティティのインスタンスへの参照であると仮定)

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
    @"ANY issues == %@", km]; 
NSArray *filteredArray = [[personForCell allObjects] 
    filteredArrayUsingPredicate:predicate]; 
if (filteredArray.count > 0) // check 
else // uncheck 

Strictyが反復はまだですが、フレームワークは、それをやっている話しますあなたのために、これらの範囲外のエラーに対処する必要はありません。あなたが関係を変更したい場合は

することは、あなたがこの情報を取得するために、同様の方法を使用する必要があります。

if (filteredArray.count > 0) [personSelected removeIssuesObject:km]; 
else [personSelected addIssuesObject:km]; 
[self.tableView reloadData]; 
+0

返信いただきありがとうございます。私はdidSelectRowAtIndexPathを確実に変更します。私はあなたの答えにも述語をつけます。 – Devroot

+0

述語を試してみると、これは私が得るものです: 'NSInvalidArgumentException'、理由: 'ALLまたはANY演算子の左辺はNSArrayまたはNSSetでなければなりません。' – Devroot

+0

'NSPredicate * predicate = [NSPredicate predicateWithFormat: @ "ANY issue ==%@"、publication]; NSArray * filteredArray = [[personForCell.pubs allObjects] filteredArrayUsingPredicate:predicate]; if(filteredArray。count> 0) { //チェック cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { //チェックを外します。 cell.accessoryType = UITableViewCellAccessoryNone; } ' – Devroot

関連する問題