Cocoa 子类化NSArrayController以限制排列对象的大小

Cocoa 子类化NSArrayController以限制排列对象的大小,cocoa,nsarraycontroller,Cocoa,Nsarraycontroller,我试图限制数组控制器中对象的数量,但如果需要,我仍然希望能够访问整个数组。我提出的一个简单解决方案是将NSArrayController子类化,并定义一个名为“limitedArrangedObjects”的新方法,该方法从实际排列的对象集中返回数量有限的对象。(我看到了,但这并不能解决我的问题。) 我希望这个属性可以通过绑定来观察,所以我设置了一个依赖项来arrangedObjects 问题是,更新arrangedObjects时,limitedArrangedObjects似乎没有观察到ar

我试图限制数组控制器中对象的数量,但如果需要,我仍然希望能够访问整个数组。我提出的一个简单解决方案是将NSArrayController子类化,并定义一个名为“limitedArrangedObjects”的新方法,该方法从实际排列的对象集中返回数量有限的对象。(我看到了,但这并不能解决我的问题。)

我希望这个属性可以通过绑定来观察,所以我设置了一个依赖项来arrangedObjects

问题是,更新arrangedObjects时,limitedArrangedObjects似乎没有观察到arrangedObjects中的值更改。我已经连接了一个NSCollectionView到limitedArrangedObjects,并且没有显示任何对象。(如果将其绑定到arrangedObjects,则所有对象都会按预期显示。)

有什么问题吗

以下是相关代码:

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

我可能会采用另一种方法,即覆盖
-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通知。

我记不起是谁/在哪里告诉我的,但我被告知观察“arrangedObjects”使用KeyPathForvalueSafefectingValueForkey的密钥:目前不适用于NSArrayController。您可以观察子键(arrangedObjects.name等),但不能直接观察arrangedObjects

因此,在我的例子中,解决方案是在我的nib文件中创建两个实例化对象,一个普通的NSArrayController和一个AFArrayController。AFArrayController具有arrangedObjects:定义如下:

- (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;
}
-(NSArray*)安排的对象;
{
return[self limitedArrayFromArray:[超级排列对象]];
}
-(NSArray*)有限阵列(NSArray*)阵列;
{
整数上限=0;
如果(楼层(NSAppKitVersionNumber)上限)计数=上限;
NSArray*arrayToReturn=[阵列对象索引:[NSIndexSet INDEXSETWITHINDEXSINRANGE:NSMakeRange(0,计数)];
返回阵列返回;
}

现在,如果我想获取所有对象,我可以在NSArrayController上观察arrangedObjects;如果我想获取有限集,我可以在AFArrayController上观察arrangedObjects;我可以在NSArrayController和AFArrayController上观察子属性。

这可能是一个优雅的解决方案,但如果我需要绑定completeArrangedObjects的子属性,它似乎不起作用。例如,我在NSArrayController中有一个名为“name”的对象属性,我可以在单独的表视图中绑定到该属性。如果重写arrangeObjects:并创建新的completeArrangedObjects属性,则无法绑定到“name”子属性,因为它会引发异常:[addObserver:forKeyPath:options:context:]不受支持。关键路径:艺术家