Отключает ли [NSManagedObject willTurnIntoFault] уведомления KVO? - PullRequest
2 голосов
/ 19 января 2011

У меня есть NSManagedObject (person), в котором зарегистрировано несколько наблюдателей для вложенного неуправляемого свойства (person.address.street, адрес неуправляемый, т.е. не определен в Базовых данных).Когда управляемый объект выходит из строя, я вызываю

person.address = nil

в willTurnIntoFault, чтобы очистить мое неуправляемое свойство.Тем не менее, KVO не удаляет наблюдателей, которые он зарегистрировал для адреса, чтобы получать уведомления об изменениях «улицы», хотя адрес соответствует KVO.Адрес освобождается, и я получаю предупреждение о том, что на него все еще зарегистрированы наблюдатели.

Единственная причина, по которой я могу выяснить, состоит в том, что willTurnIntoFault отключает уведомления KVO.Это тот случай?Есть ли обходной путь для этого.

Спасибо, Йохен

Ответы [ 2 ]

1 голос
/ 27 марта 2012

Jochen,

Такое же поведение я вижу как часть обработки слияния контекста управляемого объекта (через mergeChangesFromContextDidSaveNotification :). Для «обновленных» объектов в пользовательской информации слияния данные ядра нарушают работу объекта «локального» контекста, а затем выполняют слияние с объектом «удаленного» контекста.

Если в рамках обработки didTurnIntoFault: я освобождаю свое неуправляемое свойство (которое очень просто и определенно соответствует KVO), появляется ошибка. Интересно, что это только происходит с «вложенными» неуправляемыми свойствами. У меня есть много других неуправляемых свойств как часть моих управляемых объектов, которые являются простыми объектами (NSNumber, NSString и т. Д.), И они могут быть освобождены как часть didTurnIntoFault: обработка без каких-либо проблем. Только когда свойства> = 2 уровня глубины наблюдаются внутри неуправляемого свойства, я вижу проблему.

Я не уверен, нашли ли вы решение или нет (мне было бы очень интересно услышать, как вы продвинулись в этом), но я нашел обходной путь. Я оставляю свое неуправляемое свойство выделенным в поврежденном объекте и освобождаю его только во время prepareForDeletion.

-(void) performInventoryItemObjectSetup
{
    if ([self unitsManager] == nil) {
        [self setUnitsManager:[[[BTUnitsManager alloc] init] autorelease]];
    }
    ...
}

-(void) performInventoryItemObjectCleanup
{
    ...
}

/********************/

-(void) awakeFromInsert
{
    //NSLog(@"InventoryItem: awakeFromInsert");
    [super awakeFromInsert];
    [self performInventoryItemObjectSetup];
}

-(void) awakeFromSnapshotEvents:(NSSnapshotEventType)flags
{
    //NSLog(@"InventoryItem: awakeFromSnapshotEvents: 0x%lx", flags);

    [super awakeFromSnapshotEvents:flags];

    if (flags & NSSnapshotEventUndoDeletion) {
        [self performInventoryItemObjectSetup];
    }
}

-(void) awakeFromFetch
{
    //NSLog(@"InventoryItem: awakeFromFetch");
    [super awakeFromFetch];
    [self performInventoryItemObjectSetup];
}

-(void) didTurnIntoFault
{
    //NSLog(@"InventoryItem: didTurnIntoFault");
    [self performInventoryItemObjectCleanup];
    [super didTurnIntoFault];
}


-(void) prepareForDeletion
{
    NSLog(@"InventoryItem: prepareForDeletion");
    [self setUnitsManager:nil];
    [super prepareForDeletion];
}

Я подозреваю, что все больше людей столкнется с этой проблемой, поскольку все больше и больше приложений Core Data выпускаются с поддержкой iCloud, которая требует такого слияния как часть обработки NSPersistentStoreDidImportUbiquitousContentChangesNotification. Либо так, либо мы узнаем, что делаем неправильно: -).

Cheers, Майкл.

0 голосов
/ 27 января 2011

Вы можете использовать технику, которую опишите в http://developer.apple.com/library/mac/#releasenotes/Cocoa/FoundationOlder.html Чтобы избежать этой ошибки, вы можете использовать другой путь к ключу в привязке, который будет включать сущность с KVO-совместимостью. Пожалуйста, ознакомьтесь с примечаниями «Поддержка отладки плохого соответствия KVO» и «Советы по устранению одного вида плохого соответствия KVO».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...