Manera correcta de actualizar un NSTableView en una aplicación Core Data

Tengo un proyecto de Core Data con un NSTableView donde las columnas están vinculadas a un NSArrayController. A su vez, el contenido del controlador está vinculado al contexto de objeto gestionado principal de AppDelegate.

He sub-clasificado NSTextFieldCell para proporcionar una forma más personalizada de mostrar los datos. Todo parece funcionar bien, pero cuando enumero los objetos en el contexto y cambio un atributo, el NSArrayController no parece pasar los nuevos valores a la tabla. Sé que se están modificando a medida que los sortDescriptors funcionan y la tabla se organiza de acuerdo con los nuevos datos, pero al mismo tiempo muestra los valores antiguos. Supongo que esto se debe al reciclaje de los NSCell que muestran los datos: aunque los valores subyacentes se han cambiado en la base de datos de datos principales, no se están volviendo a dibujar.

Después de probar varias notificaciones KVO con[myArrayController willChangeValueFor: aKeyPath] y el correspondientedidChange así como simplemente[myTable reloadData]. Mi única solución ha sido desenganchar el enlace managedObjectContext del controlador y volverlo a enganchar después del procesamiento, de esta manera:

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;
        });
    });

Esto parece realmente brutal estar haciendo[myArrayController setManagedObjectContext:nil]; y luego configurándolo nuevamente solo para actualizar los contenidos de la tabla. Simplemente no puedo creer que haya hecho esto correctamente, aunque funciona bien. ¿Alguien podría avisar de una mejor manera? ¡Gracias!

ACTUALIZACIÓN: en realidad, establecer el contexto del objeto administrado no resuelve el problema. Parece que ha dejado de funcionar. Si el código se ejecuta dos veces seguidas, la aplicación simplemente se bloquea. Comenta el-setManagedObjectContext: Las líneas y el código se pueden ejecutar tantas veces como sea necesario.

En respuesta a los comentarios, mi celda personalizada usa lo siguiente para mostrarse:

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];

El controlador de matriz está configurado en la punta principal y tiene su contexto de objeto gestionado vinculado a AppDelegate. No hay solicitudes de recuperación ni predicados en la plumilla; un descriptor de clasificación está vinculado en el código de AppDelegate:

[myArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:kINDEX ascending:YES]]];

Respuestas a la pregunta(1)

Su respuesta a la pregunta