2009-12-07 16 views
7

Tengo problemas para que funcione correctamente un código NSArrayController con respaldo de datos centrales. A continuación se muestra el código:Inicialización de NSArrayController

pageArrayController = [[NSArrayController alloc] initWithContent:nil]; 
    [pageArrayController setManagedObjectContext:[self managedObjectContext]]; 
    [pageArrayController setEntityName:@"Page"]; 
    [pageArrayController setAvoidsEmptySelection:YES]; 
    [pageArrayController setPreservesSelection:YES]; 
    [pageArrayController setSelectsInsertedObjects:YES]; 
    [pageArrayController setClearsFilterPredicateOnInsertion:YES]; 
    [pageArrayController setEditable:YES]; 
    [pageArrayController setAutomaticallyPreparesContent:YES]; 
    [pageArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]]; 
    BOOL result = [pageArrayController setSelectionIndex:0]; 

Cuando intento llamar setSelectionIndex :, devuelve SÍ, indicando que la selección se ha cambiado correctamente. Sin embargo, cualquier llamada de getSelectionIndex posterior al objeto pageArrayController devuelve NSNotFound.

Lo que no entiendo es que si pongo NSArrayController en una NIB, y le permito al archivo NIB realizar la inicialización (con todos los mismos atributos en Interface Builder), el NSArrayController funciona correctamente.

¿Por qué hay una diferencia en el comportamiento? ¿El archivo NIB inicializa estos tipos de objetos de una manera especial? ¿Mi inicialización de NSArrayController es incorrecta?

Cualquier ayuda es apreciada. Gracias.

+0

No existe el método '-getSelectionIndex'. ¿Escribiste ese método tú mismo, o realmente llamaste algo diferente? –

+0

Quise decir -selectionIndex. –

Respuesta

14

Sí, las plumillas inicializan objetos de una manera especial y, a veces, puede ser difícil averiguar cómo replicar eso. Luché con esto también y finalmente encontré la respuesta en la Guía de programación de datos básicos de Apple >> Core Data y Cooca Bindings >>Automatically Prepares Content Flag (gracias a Dave Fernandes en la lista Cocoa Dev). La respuesta es que si inicializa un arraycontroller con contenido nulo, también debe realizar una búsqueda.

BOOL result; 
NSArrayController *pageArrayController = [[NSArrayController alloc] initWithContent:nil]; 
[pageArrayController setManagedObjectContext:[self managedObjectContext]]; 
[pageArrayController setEntityName:@"Page"]; 
NSError *error; 
if ([pageArrayController fetchWithRequest:nil merge:YES error:&error] == NO) 
    result = NO; 
else 
{ 
    //do all that other pageArrayController configuration stuff 
    result = [pageArrayController setSelectionIndex:0]; 
} 

Por cierto, [NSSortDescriptor sortDescriptorWithKey: @ "índice" ascendente: SÍ]] plantea una advertencia.

+0

Además, su uso de [selfobjectObjectContext] implica que ha agregado sus métodos pageArrayController a la aplicaciónDelegate. Esto no se considera una buena práctica.Debería considerar crear un objeto controlador de página separado (y modelar y ver objetos, según sea necesario para implementar el patrón MVC) que se ocupará de la funcionalidad de la página completa de su aplicación. El controlador de página o los objetos del modelo de página pueden llamar a [[delegado de NSApp] managedObjectContext] cuando sea necesario. –

+0

Gracias por esta solución, funciona perfectamente. La estructura de mi aplicación es mucho más agradable ahora que puedo crear estos controladores de matriz en código en lugar de depender de las plumillas. –

+0

¡Eres mi amigo, eres una leyenda! Pasé varios días tratando de descubrir por qué mi controlador de array no se actualizaba a medida que llegaban nuevos datos a mi almacén de Core Data desde iCloud. Ahora funciona perfectamente. Gracias. – Fin

0

En cuanto a por qué puede haber una diferencia en el comportamiento:

  1. archivos nib almacenar objetos serializados utilizando NSCoder.
  2. Probablemente esté utilizando el enlace en el lado IB de las cosas, donde en su código está configurando el contexto del objeto gestionado directamente utilizando un método set.

Tal vez usted podría intentar algo así como lo siguiente en su código:

[pageArrayController bind:@"managedObjectContext" 
       toObject:self 
       withKeyPath:@"managedObjectContext" 
        options:nil]; 

no tengo Xcode cerca de lo contrario me gustaría probar algunas cosas. Espero que esto te dé algunas pistas para que vayas en la dirección correcta.

0

¿Desde dónde está creando/configurando su controlador de array? Es posible que la pila de Datos centrales aún no esté lista, por lo tanto, su llamada a [self managedObjectContext] puede estar volviendo a cero.

Además, ¿por qué lo está creando mediante programación si puede hacerlo bien con Interface Builder? La herramienta está ahí y funciona bien (y elimina muchos posibles errores de codificación), así que a menos que tenga una buena razón para no usarla, no se está haciendo ningún favor.

+0

Bueno, en mi caso, creo NSArrayController en código como cuando uso IB, los datos enlazados en NSArrayController aún no están cargados en el método 'awakeFromNib'. ¿Sabes cómo resolver el problema en IB? – xyz

Cuestiones relacionadas