列がNSArrayControllerにバインドされているNSTableViewを備えたCoreDataプロジェクトがあります。次に、コントローラーのコンテンツは、AppDelegateのメインの管理対象オブジェクトコンテキストにバインドされます。
NSTextFieldCellをサブクラス化して、データを表示するためのよりカスタマイズされた方法を提供しました。すべてがうまく機能しているように見えますが、コンテキスト内のオブジェクトを列挙して属性を変更すると、NSArrayControllerが新しい値をテーブルに渡していないようです。sortDescriptorsが機能し、テーブルが新しいデータに従ってそれ自体を編成しているが、古い値を表示しているときに、それらが変更されていることを私は知っています。これは、データを表示するNSCellのリサイクルによるものだと思います。基本的な値はCore Data DBで変更されていますが、再描画されていません。
でさまざまなKVO通知を試した後[myArrayController willChangeValueFor: aKeyPath]
、対応するdidChange
だけでなく、単に[myTable reloadData]
。私の唯一の解決策は、コントローラーのmanagedObjectContextバインディングのフックを解除し、次のように処理後に再度フックすることでした。
self.hasBackgroundOp = YES;
self.isCancelled = NO; //can get changed with a 'cancel' button in the UI
if (self.managedObjectContext.hasChanges) {
[self. managedObjectContext save:nil];
}
[myArrayController setManagedObjectContext:nil]; //brutal un-hooking of controller
dispatch_group_t dispatchGroup = dispatch_group_create();
dispatch_group_async(dispatchGroup, dispatch_get_global_queue(0, 0), ^{
.
.
// create a thread context, set the persistent store co-ord
// and do some processing on the
// NSManagedObjects that are fetched into an array just
// for the purpose of this thread
.
.
[ctx save:&error];
//and after the processing is finished then refresh the table
dispatch_async(dispatch_get_main_queue(), ^{
[myArrayController setManagedObjectContext:self.managedObjectContext]; //this forces re-drawing of the table
self.hasBackgroundOp = NO;
self.isCancelled = NO;
});
});
[myArrayController setManagedObjectContext:nil];
これは、テーブルの内容を更新するためだけに実行してから再度設定するのは非常に残酷なようです。それはうまく機能しますが、私はこれを正しく行ったとは信じられません。誰かがより良い方法をアドバイスできますか?ありがとう!
更新:管理対象オブジェクトのコンテキストを実際に設定しても、問題は解決しません。動作を停止したようです。コードが2回続けて実行されると、アプリがハングします。行をコメントアウトする-setManagedObjectContext:
と、コードは必要な回数だけ実行できます。
コメントに応じて、私のカスタムセルは以下を使用して自分自身を表示します。
NSInteger index = [[self stringValue] integerValue] + 1;
NSAttributedString *cellText = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%lu",index] attributes:attributes];
NSRect textRect;
textRect.origin = cellFrame.origin;
textRect.origin.x += (cellFrame.size.width - cellText.size.width) / 2;
textRect.origin.y += (cellFrame.size.height - cellText.size.height) / 2;
textRect.size.width = cellText.size.width;
textRect.size.height = cellText.size.height;
[cellText drawInRect:textRect];
アレイコントローラーはメインペン先にセットアップされ、その管理対象オブジェクトコンテキストがAppDelegateにバインドされています。nibにはフェッチ要求または述語はありません-ソート記述子はAppDelegateのコードにバインドされています:
[myArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:kINDEX ascending:YES]]];