setPrimitiveValue: forKey: и отношения ко многим - PullRequest
11 голосов
/ 24 сентября 2008

Документация Apple по -setPrimitiveValue:forKey: является расплывчатой ​​в двух отношениях при использовании ее для управления отношениями со многими.

Сначала они заявляют:

Если вы попытаетесь установить отношение ко многим для нового объекта NSMutableSet, оно (в конце концов) завершится неудачей.

В конце концов?! Что это вообще значит? Будет ли это позже во время -[NSManagedObjectContext save:]? Когда управляемый объект превращается в ошибку, а затем возвращается обратно? Когда? Могу ли я написать контрольный пример для последовательного воссоздания сбоя по требованию?

Во-вторых, предоставляя пример кода для правильной обработки этого случая, они пишут:

сначала получите существующий набор, используя primitiveValueForKey: (убедитесь, что метод не возвращает nil)

Что мне делать, если / когда метод возвращает ноль? assert() это и сразу не получится, потому что это означает, что весь граф объектов поврежден, а сохранение приведет к потере данных? NSAssert() на это как предупреждение для вызывающего абонента, но нажмите на (молча ничего не делая)?

Прямо сейчас я просто напрямую назначаю желаемый NS[Mutable]Set в этом случае, например:

- (void)setChildren:(NSSet*)value_ {
    NSMutableSet *mutableRelationshipSet = [[[self primitiveValueForKey:@"children"] mutableCopy] autorelease];
    if (mutableRelationshipSet) {
        [mutableRelationshipSet setSet:value_];
        [self setPrimitiveValue:mutableRelationshipSet forKey:@"children"];
    } else {
        [self setPrimitiveValue:value_ forKey:@"children"];
    }
}

Это неправильно?

1 Ответ

6 голосов
/ 28 сентября 2008

Просто измените возвращаемое значение -primitiveValueForKey: как изменяемый набор, полагая, что его возвращаемое значение будет действовать правильно.

Обязательно используйте -willChangeValueForKey:withSetMutation:usingObjects: и -didChangeValueForKey:withSetMutation:usingObjects: для манипуляций; Вы не показали это в приведенном выше коде.

- (void)setChildren:(NSSet *)value {
    [self willChangeValueForKey:@"children" withSetMutation:NSKeyValueSetSetMutation usingObjects:value];

    NSMutableSet *primitiveValue = [self primitiveValueForKey:@"children"];

    [primitiveValue setSet:value];

    [self didChangeValueForKey:@"children" withSetMutation:NSKeyValueSetSetMutation usingObjects:value];
}

Если вы можете нацелиться на Леопарда, вам не нужно беспокоиться об этом; вместо этого вы можете использовать встроенную поддержку свойств Core Data:

#import <CoreData/CoreData.h>

@interface Folder : NSManagedObject
@property (readwrite, retain) NSSet *children;
@end

@implementation Folder
@dynamic children;
@end

Базовые данные будут генерировать не только пару получатель / установщик для свойства children, но и средства доступа с изменяемым набором, поэтому вы можете использовать -mutableSetValueForKey: для него и манипулировать результатом с минимальными издержками. *

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