Полученные свойства как свойства подкласса NSManagedObject - PullRequest
2 голосов
/ 03 июля 2010

У меня есть подкласс NSManagedObject (NSMO) под названием Team.Команда имеет отношения один ко многим с другим подклассом NSMO, который называется Контракт.Контракт имеет 1-к-1 с игроком (другой NSMO).Я хотел бы упростить мой код, который использует Team, и иметь возможность просто ссылаться на ее «игроков».Игроки будут просто массивом игроков, у которых есть контракт с данной командой.

Я попытался создать извлеченное свойство, называемое игроками, в инструменте моделирования данных XCode с небольшим успехом.Я испробовал много разных подходов, но наиболее разумно назвать его «игроки», указать место назначения в качестве игрока и, наконец, использовать в качестве предиката «contract.team.name == SELF».

В моем классе Team у меня есть свойство NSArray, называемое Players (с реализацией is @dynamic Players).Когда я NSLog (@ "% @", self.players) он выходит из системы ...

Relationship fault for (<NSFetchedPropertyDescription: 0x6d19cd0>), name players, isOptional 1, isTransient 1, entity Team, renamingIdentifier players, validation predicates (
), warnings (
), versionHashModifier (null), fetchRequest <NSFetchRequest: 0x6d1a080> (entity: Player; predicate: (contract.team.name == SELF); sortDescriptors: ((null)); type: NSManagedObjectResultType; ) on 0x6d38550

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

Так что я думаю, что у меня следующие вопросы: 1) Какой тип это свойство извлечет в моем подклассе NSMO.(Я сделал это NSArray, но, очевидно, это NSFetchedPropertyDescription) 2) Какой код я могу использовать для получения массива или установки?

Спасибо!Rob

Ответы [ 2 ]

9 голосов
/ 04 июля 2010

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

Базовые данные используют ошибки в отношениях, чтобы избежать необходимости загружать огромное количество объектов в память только для того, чтобы найти один небольшой фрагмент данных. Предположим, у вас есть связь с 1000 управляемых объектов на другой стороне, и вам нужно одно целочисленное значение от одного из этих управляемых объектов. Без ошибок Core Data должна была бы загрузить 1000 объектов в память только для того, чтобы найти и извлечь 32-битные данные. При сбое Core Data знает , где целочисленное значение, и может получить этот один объект с одним значением.

Вы можете рассматривать извлеченное свойство как массив. Возьмите случай этого простого подкласса управляемого объекта, в котором theFetchedProperty является извлеченным свойством с предикатом "TestEntity.order>5"

@interface TestEntityMO :  NSManagedObject  
{}
@property (nonatomic, retain) NSNumber * order;
@property(nonatomic, retain)  NSArray *theFetchedProperty;

Настроить так:

TestEntityMO *testMO;
for (int i=0; i<10; i++) {
    testMO=[NSEntityDescription insertNewObjectForEntityForName:@"TestEntity" inManagedObjectContext:self.managedObjectContext];
    testMO.order=[NSNumber numberWithInt:i];
}

Затем запишите последний созданный объект TestEntityMO. * в первый раз вы регистрируете свойство, оно возвращает ошибку:

NSLog(@"testMO.theFetchedProperty == %@",testMO.theFetchedProperty);

выходы

testMO.theFetchedProperty == Relationship fault for (<NSFetchedPropertyDescription: 0x3d19210>), //... rest removed for brevity

... но вы можете записать количество выбранных свойств как массив:

NSLog(@"[testMO.theFetchedProperty count] == %d",[testMO.theFetchedProperty count] );

... выходы:

[testMO.theFetchedProperty count] == 4

Вы можете получить объект по индексу, как массив:

NSLog(@"[testMO.theFetchedProperty objectAtIndex:0] == %@",[testMO.theFetchedProperty objectAtIndex:0]);

... выводит описание объекта TestEntityMO (которое может быть или не быть ошибкой. В этом случае нет):

[testMO.theFetchedProperty objectAtIndex:0] == <TestEntityMO: 0x3d20a70> (entity: TestEntity; id: 0x3d20ab0 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A11> ; data: {
    order = 9;
    theFetchedProperty =     (
        0x3d20ab0 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A11>,
        0x3d20a00 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A10>,
        0x3d20880 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A8>,
        0x3d20970 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A9>
    );
})

Регистрация значения атрибута случайного объекта:

NSLog(@"[[testMO.theFetchedProperty objectAtIndex:0] order] == %@",[[testMO.theFetchedProperty objectAtIndex:1] order]);

... выходы:

[[testMO.theFetchedProperty objectAtIndex:1] order] == 8

Однако, если вы вошли в журнал извлеченного свойства во второй раз после того, как вы запустили извлечение по указанному выше коду, вы получите реальные объекты:

NSLog(@"testMO.theFetchedProperty == %@",testMO.theFetchedProperty);

... выходы:

testMO.theFetchedProperty == Relationship objects for (
    <TestEntityMO: 0x3d20a70> ... ; 
data: {
    order = 9;
    theFetchedProperty =     (
        0x3d20ab0 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A11>,
        0x3d20a00 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A10>,
        0x3d20880 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A8>,
        0x3d20970 <x-coredata:///TestEntity/t3A79EE49-39F4-4FCA-8E25-0C28B8E0E01A9>
    );
}),...

В сумме вы можете:

  1. Обрабатывать извлеченные отношения так же, как NSArrays в коде.
  2. Как и во всех управляемых объектах, вы часто будете видеть ошибку, если будете регистрировать объект напрямую.
1 голос
/ 04 июля 2010

Разве вы не можете просто позвонить [aTeam valueForKeyPath:@"contracts.player"]?

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