Objective c 在NSTableView中,如何根据所选内容对项目进行排序?

Objective c 在NSTableView中,如何根据所选内容对项目进行排序?,objective-c,macos,cocoa,nstableview,Objective C,Macos,Cocoa,Nstableview,我正在Objective-C中开发一个macOS应用程序。我想添加一个功能,对NSTableView进行排序,以便在其他项之前显示所选项。我的代码是: NSUInteger idx = [self.itemsTableView.selectedRowIndexes firstIndex]; NSMutableArray *selectedObjects = [NSMutableArray new]; while (idx != NSNotFound) { // do work wit

我正在Objective-C中开发一个macOS应用程序。我想添加一个功能,对NSTableView进行排序,以便在其他项之前显示所选项。我的代码是:

NSUInteger idx = [self.itemsTableView.selectedRowIndexes firstIndex];

NSMutableArray *selectedObjects = [NSMutableArray new];

while (idx != NSNotFound)
{
    // do work with "idx"
    // NSLog (@"The current index is %lu", (unsigned long)idx);

    [selectedObjects addObject:self.items[idx]];
    // get the next index in the set
    idx = [self.itemsTableView.selectedRowIndexes indexGreaterThanIndex:idx];
}
self.items = [self.unFilteredItems sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {

        BOOL obj1Exists = [selectedObjects containsObject:obj1];
        BOOL obj2Exists = [selectedObjects containsObject:obj2];


        if (obj1Exists && !obj2Exists) {
            return NSOrderedAscending;
        }
        if (obj1Exists && obj2Exists) {
            return NSOrderedSame;
        }
        if (!obj1Exists && !obj2Exists) {
            return NSOrderedSame;
        }
        if (!obj1Exists && obj2Exists) {
            return NSOrderedDescending;
        }

        return NSOrderedSame;

    }];

    [self.itemsTableView reloadData];
不幸的是,在大约70000个项目和4500个项目的选择上,比较法花费了太多的时间。有人能给我指出这个问题的另一种解决办法吗?谢谢你的帮助

编辑:

我现在尝试了另一种解决方案,它被证明更快,但仍然不够快:

NSUInteger idx = [self.myMessagesTableView.selectedRowIndexes firstIndex];

NSMutableArray *selectedObjects = [NSMutableArray new];

while (idx != NSNotFound)
{
    // do work with "idx"
    // NSLog (@"The current index is %lu", (unsigned long)idx);

    [selectedObjects addObject:self.myMessages[idx]];
    // get the next index in the set
    idx = [self.myMessagesTableView.selectedRowIndexes indexGreaterThanIndex:idx];
}

NSMutableArray *unselectedObjects = [NSMutableArray new];

[self.unFilteredItems enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

    if (![selectedObjects containsObject:obj]) {
        [unselectedObjects addObject:obj];
    }

}];


self.items = selectedObjects;

self.items = [self.items arrayByAddingObjectsFromArray:unselectedObjects];

[self.itemsTableView reloadData];

我希望有人能给我指出正确的方向,可能会尝试使用选择索引而不是选择对象的数组。再次感谢。

我找到了一种工作速度非常快的方法,但它并不优雅,我认为它肯定打破了MVC模式,但它目前仍然有效,因此任何其他更好的解决方案都是非常受欢迎的。我现在使用的代码是:

NSUInteger idx = [self.itemsTableView.selectedRowIndexes firstIndex];

NSMutableArray *selectedObjects = [NSMutableArray new];

while (idx != NSNotFound)
{
    // do work with "idx"
    // NSLog (@"The current index is %lu", (unsigned long)idx);
    [self.items[idx] setValue:@YES forKey:@"isItemSelected"];
    [selectedObjects addObject:self.items[idx]];
    // get the next index in the set
    idx = [self.itemsTableView.selectedRowIndexes indexGreaterThanIndex:idx];
}

NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"isItemSelected" ascending:NO];

self.items = [self.unFilteredItems sortedArrayUsingDescriptors:@[descriptor]];


[self.itemsTableView reloadData];

NSMutableIndexSet *set = [[NSMutableIndexSet alloc] init];

NSUInteger a = 0;

for (a=0;a<[selectedObjects count];a++) {

    [set addIndex:a];

}

[self.itemsTableView selectRowIndexes:set byExtendingSelection:NO];

[selectedObjects enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [obj removeObjectForKey:@"isItemSelected"];
}];

非常感谢您的关注。

获取选定对象并附加未选定对象如何

NSArray *selectedObjects = [self.items objectsAtIndexes:self.itemsTableView.selectedRowIndexes];
// invert selectedRowIndexes
NSMutableIndexSet *invertedSelection = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.items.count)];
[invertedSelection removeIndexes:self.itemsTableView.selectedRowIndexes];
NSArray *unselectedObjects = [self.items objectsAtIndexes:invertedSelection];
self.items = [selectedObjects arrayByAddingObjectsFromArray:unselectedObjects];
self.itemsTableView.selectedRowIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, selectedObjects.count)];
[self.itemsTableView reloadData];
或删除选定对象并将其插入顶部

NSMutableArray *mutableItems = [self.items mutableCopy];
NSArray *selectedObjects = [self.items objectsAtIndexes:self.itemsTableView.selectedRowIndexes];
[mutableItems removeObjectsAtIndexes:self.itemsTableView.selectedRowIndexes];
NSindexSet *selectedIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, selectedObjects.count)]
[mutableItems insertObjects:selectedObjects atIndexes:selectedIndexes];
self.items = [mutableItems copy];
self.itemsTableView.selectedRowIndexes = selectedIndexes;
[self.itemsTableView reloadData];

我没有对此进行测试。

谢谢Willeke,您的解决方案的速度大约是我的3倍。再次感谢。