NSArrayController связывает детали в модели 1: многие: многие - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть простая программа, иллюстрирующая, что я пытаюсь сделать в моей настоящей программе. У меня есть отношение 1 ко многим отношениям 1 к многим, и я не могу заставить редактирование нескольких выделений работать должным образом, если верхний уровень имеет множественное выделение:

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>

@interface ManyMany : NSObject

@property int value1;
@property int value2;

@end

@implementation ManyMany

- (id)copyWithZone:(NSZone *)zone {
    ManyMany *m = [[ManyMany allocWithZone:zone] init];
    m.value1 = self.value1;
    m.value2 = self.value2;

    return m;
}

- (BOOL)isEqual:(ManyMany *)other {
    if (other == nil) {
        return NO;
    }

    if (self.value1 == other.value1 && self.value2 == other.value2) {
        return YES;
    }

    return NO;
}

@end

@interface Many : NSObject

@property NSArray< ManyMany * > *manyManys;

@end

@implementation Many

@end

@interface One : NSObject 

@property NSArray< Many * > *manys;

@end

@implementation One

@end

@interface MyObserver : NSObject

@property NSObject *value;

@end

@implementation MyObserver

@end

int main()
{
    One *one = [[One alloc] init];
    one.manys = @[ [[Many alloc] init], [[Many alloc] init] ];
    one.manys[0].manyManys = @[ [[ManyMany alloc] init], [[ManyMany alloc] init] ];
    one.manys[1].manyManys = @[ [[ManyMany alloc] init], [[ManyMany alloc] init] ];

    NSArrayController *manyController = [[NSArrayController alloc] init];
    manyController.objectClass = [Many class];

    NSArrayController *manyManyController = [[NSArrayController alloc] init];
    manyManyController.objectClass = [ManyMany class];

    [manyController bind:NSContentArrayBinding toObject:one withKeyPath:@"manys" options:nil];
    [manyManyController bind:NSContentArrayBinding toObject:manyController withKeyPath:@"selection.manyManys" options:nil];

    MyObserver *o = [[MyObserver alloc] init];
    [o bind:@"value" toObject:manyManyController withKeyPath:@"selection.value1" options:nil];

    [manyController setSelectionIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,2)]];
    [manyManyController setSelectionIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,2)]];

    [manyManyController setValue:@(2) forKeyPath:@"selection.value1"];

    NSLog(@"contents:");
    Many *m;
    for (m in one.manys) {
        NSLog(@"many @ %p", m);
        ManyMany *mm;
        for (mm in m.manyManys) {
            NSLog(@"manyMany @ %p", mm);
            NSLog(@" %d %d", mm.value1, mm.value2);
        }
    }
}

В результате этого отображается первая группа из 2 установлены правильно, а не все четыре. Если я вместо этого изменю привязку содержимого ManyManyController на selectedObjects.manyManys, тогда установите setValue: forKeyPath: правильно установит все 4, однако привязка к наблюдателю вызовет sh.

Чего мне в принципе не хватает

1 Ответ

0 голосов
/ 17 апреля 2020
  1. Вам не хватает привязки массива содержимого для множественного выбора.

Индексированная коллекция, указывающая элементы, которые NSArrayController обрабатывает как свои объекты содержимого, когда привязка contentArray или contentObject возвращает маркер множественного выбора.

[manyManyController bind:NSContentArrayForMultipleSelectionBinding toObject:manyController withKeyPath:@"selection.@unionOfArrays.manyManys" options:nil];
Привязка contentArray не возвращает маркер множественного выбора, поскольку Many.manys s равны. Включение alwaysUsesMultipleValuesMarker позволит исправить это, но также отключит многократное редактирование атрибутов Many.
manyController.alwaysUsesMultipleValuesMarker = YES;
Выбрать все 4 четыре ManyMany с.
[manyManyController setSelectionIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,4)]];
...