2009-12-07 4 views
7

Je rencontre des problèmes pour obtenir un NSArrayController soutenu par les données de base pour fonctionner correctement dans mon code. Ci-dessous mon code:Initialisation 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]; 

Lorsque je tente d'appeler setSelectionIndex :, il retourne OUI, ce qui indique que la sélection a été modifié avec succès. Cependant, tous les appels getSelectionIndex suivants à l'objet pageArrayController retournent NSNotFound. Ce que je ne comprends pas, c'est que si je mets le NSArrayController dans une NIB et que je permets au fichier NIB d'effectuer l'initialisation (avec tous les mêmes attributs dans Interface Builder), NSArrayController fonctionne correctement.

Pourquoi y a-t-il une différence de comportement? Est-ce que le fichier NIB initialise ces types d'objets d'une manière spéciale? Mon initialisation de NSArrayController est-elle incorrecte?

Toute aide est appréciée. Merci.

+0

Il n'existe pas de méthode '--getSelectionIndex'. Avez-vous écrit une telle méthode vous-même ou avez-vous appelé quelque chose de différent? –

+0

Je voulais dire -selectionIndex. –

Répondre

14

Oui, les pointes initialisent les objets d'une manière spéciale et parfois il peut être difficile de comprendre comment répliquer cela. J'ai aussi lutté avec cela et j'ai finalement trouvé la réponse dans le Core Data Programming Guide d'Apple >> Core Data et Cooca Bindings >>Automatically Prepares Content Flag (merci à Dave Fernandes sur la liste Cocoa Dev). La réponse est que si vous initialisez un arraycontroller avec un contenu nul, vous devez également effectuer une extraction.

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: @ "index" croissant: OUI]] soulève un avertissement.

+0

En outre, votre utilisation de [self managedObjectContext] implique que vous avez ajouté vos méthodes pageArrayController à appDelegate. Ce n'est pas considéré comme une bonne pratique.Vous devriez vraiment chercher à créer un objet contrôleur de page séparé (et à modéliser et afficher des objets, si nécessaire pour implémenter le modèle MVC) qui s'occupera de la fonctionnalité de la page entière de votre application. Le contrôleur de page ou les objets de modèle de page peuvent appeler [[délégué NSApp] managedObjectContext] si nécessaire. –

+0

Merci pour cette solution, cela fonctionne parfaitement. Ma structure d'application est beaucoup plus agréable maintenant que je peux créer ces contrôleurs de tableau dans le code plutôt que de compter sur des pointes. –

+0

Vous mon ami, êtes une légende! J'ai passé des jours à essayer de comprendre pourquoi mon contrôleur RAID ne se mettait pas à jour à mesure que de nouvelles données venaient d'iCloud dans mon magasin Core Data. Maintenant, cela fonctionne parfaitement. Je vous remercie. – Fin

0

En ce qui pourquoi il peut y avoir une différence de comportement:

  1. fichiers nib stocker des objets sérialisés à l'aide NSCoder.
  2. Vous utilisez probablement une liaison sur le côté IB des objets, où dans votre code vous définissez le contexte d'objet géré directement à l'aide d'une méthode set.

Peut-être que vous pourriez essayer quelque chose comme ce qui suit dans votre code:

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

Je n'ai pas Xcode à proximité sinon je voudrais essayer somethings. Espérons que cela vous donne quelques indices pour vous aider à aller dans la bonne direction.

0

D'où créez-vous/configurez-vous votre contrôleur RAID? La pile de données de base n'est peut-être pas encore prête, votre appel à [self managedObjectContext] peut donc renvoyer zéro.

Aussi, pourquoi créez-vous par programme si vous pouvez le faire très bien avec Interface Builder? L'outil est là et fonctionne bien (et élimine de nombreuses erreurs de codage possibles), donc à moins d'avoir une bonne raison de ne pas l'utiliser, vous ne vous faites aucune faveur.

+0

Eh bien, dans mon cas, je crée NSArrayController dans le code comme lorsque vous utilisez IB, les données liées dans NSArrayController ne sont pas encore chargées dans la méthode 'awakeFromNib'. Savez-vous comment résoudre le problème dans IB? – xyz