子类化NSArrayController以限制arrangeObjects的大小

时间:2010-05-07 01:40:37

标签: cocoa nsarraycontroller

我正在尝试限制数组控制器中的对象数量,但如果需要,我仍然希望能够访问整个数组。我提出的一个简单的解决方案是子类化NSArrayController,并定义一个名为“limitedArrangedObjects”的新方法,该方法从实际排列的对象集中返回有限数量的对象。 (我见过Limiting the number of objects in NSArrayController,但这并没有解决我的问题。)

我希望通过绑定可以观察到这个属性,所以我在其上设置了依赖于的arrangeObjects。

问题是,当更新arrangeObjects时,limitedArrangedObjects似乎没有观察到arrangeObjects中的值更改。我已经将NSCollectionView连接到restrictedArrangedObjects,并且正在显示零对象。 (如果我将它绑定到arrangeObjects,则所有对象都会按预期显示。)

有什么问题?

以下是相关代码:

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

2 个答案:

答案 0 :(得分:1)

我可能会采用不同的方法,即覆盖-arrangeObjects:,它可以过滤掉对象,然后设置一个辅助属性,如completeArrangedObjects,以便您访问整个数组。它看起来像这样:

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

然后你只需要将你的NSCollectionView绑定到arrangedObjects,因为你正在使用completeArrangedObjects的setter,如果你想绑定它,它也应该在适当的时候触发KVO通知

答案 1 :(得分:-1)

我不记得在哪里/谁告诉我这个,但我被告知使用keyPathsForValuesAffectingValueForKey观察“arrangeObjects”键:目前不适用于NSArrayControllers。您可以观察子键(arrangeObjects.name等),但不能直接观察arrangeObjects。

所以,我的解决方案是在我的nib文件中创建两个实例化对象,一个普通的NSArrayController和一个AFArrayController。 AFArrayController已安排了对象:定义如下:

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

现在,我可以在NSArrayController上观察arrangeObjects,如果我想获取所有对象,或者如果我想获得有限的集合,则可以在AFArrayController上使用arrangeObjects,我可以在NSArrayController和AFArrayController上观察子属性。 / p>