Я отследил ошибку. Встречается в willChangeValueForKey:withSetMutation:usingObjects:
.
Этот вызов вызывает цепочку уведомлений, которые, возможно, трудно отследить, и, конечно, изменения в одном респонденте могут иметь последствия для другого, что, как я подозреваю, объясняет, почему Apple ничего не сделала.
Тем не менее, это нормально в Set, и это только операции Set на OrderedSet, которые работают со сбоями. Это означает, что есть только четыре метода, которые необходимо изменить. Поэтому все, что я сделал, это преобразовал операции Set в их эквивалентные операции Array. Они работают идеально и минимальные (но необходимые) накладные расходы.
На критическом уровне это решение страдает от одного критического недостатка; если вы добавляете объекты, и один из объектов уже существует, то он либо не добавляется, либо перемещается в конец упорядоченного списка (я не знаю, какой). В любом случае ожидаемый упорядоченный индекс объекта к тому времени, когда мы достигаем didChange
, отличается от того, что ожидалось. Это может сломать приложения некоторых людей, но это не повлияет на мое, так как я только добавляю новые объекты или подтверждаю их окончательное местоположение перед тем, как добавить их.
- (void)addChildrenObject:(BAFinancialItem *)value {
if ([self.children containsObject:value]) {
return;
}
NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:self.children.count];
[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
[[self primitiveValueForKey:ChildrenKey] addObject:value];
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
}
- (void)removeChildrenObject:(BAFinancialItem *)value {
if (![self.children containsObject:value]) {
return;
}
NSIndexSet * indexSet = [NSIndexSet indexSetWithIndex:[self.children indexOfObject:value]];
[self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
[[self primitiveValueForKey:ChildrenKey] removeObject:value];
[self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
}
- (void)addChildren:(NSOrderedSet *)values {
if ([values isSubsetOfOrderedSet:self.children]) {
return;
}
NSIndexSet * indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.children.count, values.count)];
[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
[[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values];
[self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];
}
- (void)removeChildren:(NSOrderedSet *)values {
if (![self.children intersectsOrderedSet:values]) {
return;
}
NSIndexSet * indexSet = [self.children indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [values containsObject:obj];
}];
[self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
[[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values];
[self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexSet forKey:ChildrenKey];
}
Конечно, есть более простое решение. это выглядит следующим образом;
- (void)addChildrenObject:(BAFinancialItem *)value {
if ([self.children containsObject:value]) {
return;
}
[self insertObject:value inChildrenAtIndex:self.children.count];
}
- (void)removeChildrenObject:(BAFinancialItem *)value {
if (![self.children containsObject:value]) {
return;
}
[self removeObjectFromChildrenAtIndex:[self.children indexOfObject:value]];
}
- (void)addChildren:(NSOrderedSet *)values {
if ([values isSubsetOfOrderedSet:self.children]) {
return;
}
[self insertChildren:values atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(self.children.count, values.count)]];
}
- (void)removeChildren:(NSOrderedSet *)values {
if (![self.children intersectsOrderedSet:values]) {
return;
}
[self removeChildrenAtIndexes:[self.children indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [values containsObject:obj];
}]];
}
Я бы хотел увидеть лучший менеджер пакетов для emacs. Может быть, что-то вроде RIP ? ELPA выглядит интересно, но мне не нравится, что он пытается разместить и объединить все пакеты. Я бы предпочел иметь возможность добавлять модули из любого найденного мной репозитория git или cvs. Я также хотел бы, чтобы модули в этом теоретическом диспетчере пакетов имели стандартный способ включения значков и информационного файла. Наконец, я бы хотел иметь чрезвычайно простой метод компиляции всех модулей.
Я попытался сделать мои файлы emacs модулями в этом стиле (см. Мой репозиторий github emacs.d ), хотя я бы с радостью отказался от этого, если бы что-то получше получило широкую поддержку.
Реализация elisp, которая отличается от уровня искусства 1985 года. Я серьезно - глобальные переменные везде? Парсер без повторного входа? Как будто они не хотят, чтобы людей работали над этим. Я кратко рассмотрел адаптацию Emacs к разделяемой библиотеке, но не смог обойтись даже с синтаксическим анализом файлов elisp.
Я желаю стандартного автозаполнения с распознаванием кода (hippie-expand немного устарел) и лучшего графического интерфейса для поддержки таких вещей, как текущий список кандидатов на завершение, который должен быть не хуже этого из VIM.
Поскольку у вас есть Cx Mc M-butterfly, вам больше ничего не нужно.