2009-12-07 20 views
7

Sto riscontrando problemi nel far funzionare correttamente NSArrayController con i dati di base nel mio codice. Qui di seguito è il mio codice:Inizializzazione 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]; 

Quando tento di chiamare setSelectionIndex :, ritorna SI, che indica che la selezione è stata modificata con successo. Tuttavia, ogni successiva chiamata getSelectionIndex all'oggetto pageArrayController restituisce NSNotFound.

Quello che non capisco è che se metto NSArrayController in un NIB e consento al file NIB di eseguire l'inizializzazione (con tutti gli stessi attributi in Interface Builder), NSArrayController funziona correttamente.

Perché c'è una differenza di comportamento? Il file NIB inizializza questi tipi di oggetti in un modo speciale? La mia inizializzazione di NSArrayController è errata?

Qualsiasi aiuto è apprezzato. Grazie.

+0

Non esiste un metodo '-getSelectionIndex'. Hai scritto tu stesso un metodo, o in realtà hai chiamato qualcosa di diverso? –

+0

Intendevo -selectionIndex. –

risposta

14

Sì, i pennini inizializzano gli oggetti in un modo speciale ea volte può essere difficile capire come replicarli. Ho lottato anche con questo e alla fine ho trovato la risposta nella Guida alla programmazione dei dati di base di Apple >> Core Data e Cooca Bindings >>Automatically Prepares Content Flag (grazie a Dave Fernandes nell'elenco Cocoa Dev). La risposta è che se si inizializza un controller di array con contenuto nullo, è necessario eseguire anche il recupero.

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

BTW, [NSSortDescriptor sortDescriptorWithKey: @ "indice" ascendente: SI]] genera un avviso.

+0

Inoltre, l'utilizzo di [self managedObjectContext] implica che i metodi pageArrayController sono stati aggiunti all'appDelegate. Questo non è considerato una buona pratica.Dovresti davvero cercare di creare un oggetto separato del controllore di pagina (e modellare e visualizzare gli oggetti, se necessario per implementare il pattern MVC) che si occuperà dell'intera funzionalità della pagina dell'applicazione. Se necessario, il controllore di pagina o gli oggetti del modello di pagina possono chiamare [[delegato NSApp] managedObjectContext]. –

+0

Grazie per questa soluzione, funziona perfettamente. La mia struttura di app è molto più bella ora che posso creare questi controller di array nel codice piuttosto che fare affidamento sui pennini. –

+0

Tu amico mio, sono una leggenda! Ho passato giorni a cercare di capire perché il mio controller di array non si stava aggiornando quando nuovi dati sono arrivati ​​nel mio negozio di Core Data da iCloud. Ora funziona perfettamente. Grazie. – Fin

0

Per quanto riguarda il motivo per cui ci può essere una differenza di comportamento:

  1. file pennino memorizzare oggetti serializzati utilizzando NSCoder.
  2. Probabilmente stai usando il binding sul lato IB delle cose, dove nel tuo codice stai impostando il contesto dell'oggetto gestito direttamente usando un metodo set.

Forse si potrebbe provare qualcosa di simile al seguente nel codice:

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

Non ho Xcode vicino altrimenti avrei cercato quarantina. Speriamo che questo ti dia qualche indizio per farti andare nella giusta direzione.

0

Da dove si sta creando/configurando il controller di array? Lo stack dei Core Data potrebbe non essere ancora pronto, quindi la tua chiamata a [self managedObjectContext] potrebbe tornare nil.

Inoltre, perché lo stai programmando se riesci a farlo bene con Interface Builder? Lo strumento è lì e funziona bene (ed elimina molti possibili errori di codifica), quindi a meno che tu non abbia una buona ragione per non usarlo, non ti stai facendo alcun favore.

+0

Bene nel mio caso creo NSArrayController nel codice come quando si usa IB, i dati associati in NSArrayController non sono ancora stati caricati nel metodo 'awakeFromNib'. Sai come risolvere il problema in IB? – xyz

Problemi correlati