2010-05-07 3 views
3

J'essaie de limiter le nombre d'objets dans un contrôleur RAID, mais je veux toujours pouvoir accéder à la totalité de la matrice, si nécessaire. Une solution simple que j'ai trouvé était de sous-classer NSArrayController, et de définir une nouvelle méthode nommée "limitedArrangedObjects", qui retourne un nombre limité d'objets de l'ensemble réel des objets arrangés. (J'ai vu Limiting the number of objects in NSArrayController, mais cela ne résout pas mon problème.)Sous-classe NSArrayController afin de limiter la taille de arrangedObjects

Je veux que cette propriété soit observable via les bindings, donc j'ai mis une dépendance à arrangedObjects dessus.

Le problème est que, lorsque arrangedObjects est mis à jour, limitedArrangedObjects ne semble pas observer le changement de valeur dans arrangedObjects. J'ai connecté un NSCollectionView à limitedArrangedObjects, et zéro objets sont affichés. (Si je le lie à arrangedObjects à la place, tous les objets s'affichent comme prévu.)

Quel est le problème?

Voici le code correspondant:

@property (readonly) NSArray *limitedArrangedObjects; 

- (NSArray *)limitedArrangedObjects; 
{ 
    NSArray *arrangedObjects = [super arrangedObjects]; 

    NSUInteger upperLimit = 10000; 

    NSUInteger count = [arrangedObjects count]; 
    if (count > upperLimit) count = upperLimit; 
    arrayToReturn = [arrangedObjects subarrayWithRange:NSMakeRange(0, count)]; 


    return arrayToReturn; 
} 


+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key; 
{ 
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key]; 

    if ([key isEqualToString:@"limitedArrangedObjects"]) { 
     NSSet *affectingKeys = [NSSet setWithObjects:@"arrangedObjects",nil]; 
     keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKeys]; 
    } 

    return keyPaths; 
} 

Répondre

-1

Je ne me souviens pas où/qui m'a dit cela, mais j'ai été informé que l'observation de la clé "arrangedObjects" en utilisant keyPathsForValuesAffectingValueForKey: ne fonctionne pas actuellement pour NSArrayControllers. Vous pouvez observer des sous-clés (arrangedObjects.name, etc.), mais vous ne pouvez pas observer les orderedObjects directement. Donc, la solution dans mon cas était de créer deux objets instanciés dans mon fichier nib, un NSArrayController normal et un AFArrayController. AFArrayController a arrangedObjects: défini comme tel:

- (NSArray *)arrangedObjects; 
{ 
    return [self limitedArrayFromArray:[super arrangedObjects]]; 
} 

- (NSArray *)limitedArrayFromArray:(NSArray *)theArray; 
{ 
    NSUInteger upperLimit = 0; 
    if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_5) { 
     upperLimit = 500; 
    } else { 
     upperLimit = 10000; 
    } 

    NSUInteger count = [theArray count]; 
    if (count > upperLimit) count = upperLimit; 
    NSArray *arrayToReturn = [theArray objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, count)]]; 


    return arrayToReturn; 
} 

Maintenant, je peux observer arrangedObjects sur NSArrayController si je veux obtenir tous les objets ou arrangedObjects sur le AFArrayController si je veux obtenir le nombre limité, et je peux observer sous-propriétés sur NSArrayController et AFArrayController.

1

je ne serais probablement adopter une approche différente, qui serait de passer outre -arrangeObjects:, qui peut filtrer les objets, puis définir une propriété auxiliaire comme completeArrangedObjects pour vous permettre d'accéder à l'ensemble tableau. Il avait l'air quelque chose comme ceci:

- (NSArray*)arrangeObjects:(NSArray*)originalObjects 
{ 
    NSArray* arrayToReturn; 
    NSUInteger upperLimit = 10000; 

    NSUInteger count = [originalObjects count]; 
    if (count > upperLimit) count = upperLimit; 
    arrayToReturn = [arrangedObjects subarrayWithRange:NSMakeRange(0, count)]; 
    [self setCompleteArrangedObjects:originalObjects]; 
    return arrayToReturn; 
} 

alors vous simplement lier votre NSCollectionView à arrangedObjects, et puisque vous utilisez un setter pour completeArrangedObjects, qui devrait également déclencher des notifications KVO, le cas échéant, si vous voulez lier à lui aussi.

+0

Cela pourrait potentiellement être une solution élégante, mais cela ne semble pas fonctionner si j'ai besoin de lier des sous-propriétés de completeArrangedObjects. Par exemple, j'ai une propriété des objets dans le NSArrayController appelée "nom", et je peux lier à cela dans une vue de table séparée. Si j'Override arrangeObjects: et créer une nouvelle propriété completeArrangedObjects, je ne peux pas lier au "nom" sous-propriété, comme il jette une exception: [ addObserver: forKeyPath: Options: contexte:] ne sont pas pris en charge. Chemin clé: artiste –

Questions connexes