Базовые данные iPhone: должны ли трансформируемые атрибуты преобразовываться только в данные?

Я использовал трансформируемые атрибуты в основных данных для преобразования сложных объектов, таких как изображения и цвета, в необработанные данные. Я взял это...

Идея трансформируемых атрибутов заключается в том, что вы получаете доступ к атрибуту как к нестандартному типу, но за кулисами Core Data использует экземпляр NSValueTransformer для преобразования атрибута в экземпляр NSData и обратно. Затем Core Data сохраняет экземпляр данных в постоянном хранилище.

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

Мне просто пришло в голову, что это может быть не так. Документация может просто говорить о наиболее распространенном случае. IIRC, в привязках Cocoa преобразования могут быть в значительной степени произвольными. Можно преобразовать, скажем, NSURL в NSString для отображения, а затем обратить его.

Прежде чем тратить время на эксперименты и, возможно, получить запутанный результат, я подумал, знает ли кто-нибудь наверняка, выполняется ли преобразование только в данные и только из них.


person TechZen    schedule 02.02.2010    source источник


Ответы (2)


Правильный. Вы должны преобразовать свой атрибут в объект NSData. Вам нужно будет сериализовать NSURL в NSData -- и преобразователь NSKeyedUnarchiveFromDataTransformerName по умолчанию сделает это за вас.

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

Нет никакого способа применить его, но вы действительно не хотите использовать строковое свойство вне класса вашей сущности. Обычно я делаю определение @property для строкового атрибута приватным, чтобы напомнить себе не использовать его.

person Alex    schedule 02.02.2010
comment
Да, я уже некоторое время использую тот же подход, я просто хотел проверить, не понял ли я что-то неправильно. - person TechZen; 03.02.2010
comment
Но в официальном документе показан пример фрагмента кода, использующего + (Class)transformedValueClass { return [NSString class]; }, кажется, NSValueTransformer можно преобразовать в NSString.. Я совершенно запутался.. :S - person Kjuly; 18.02.2012
comment
@Kjuly Вы совершенно правы. На самом деле пользовательский NSValueTransformer позволяет преобразовать ваш объект в объект, который может быть сохранен Core Data. Таким образом, вы можете преобразовать свой NSURL в NSString или NSData. NSKeyedUnarchiveFromDataTransformerName – это имя существующего преобразователя, который преобразует <NSCoding>-совместимые классы в NSData без дополнительного кода. - person Arnaud; 27.08.2013
comment
Отлично. Именно то, что мне нужно было знать. - person fatuhoku; 02.04.2014

У меня недостаточно баллов для комментариев, поэтому я должен внести свой вклад в виде ответа. Я просто попытался сделать именно то, что предложил @Amaud, используя NSValueTransformer для преобразования NSURL объектов в NSString объектов для трансформируемого атрибута. К сожалению, Core Data по-прежнему ожидает экземпляр NSData от преобразователя, независимо от transformedValueClass. Core Data по-прежнему создает базу данных SQLite со столбцом BLOB для этого трансформируемого атрибута, а сохранение сущностей приводит к сбою с uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString bytes]: unrecognized selector sent to instance 0x608000075bc0'. Core Data пытается вызвать [NSData bytes] в экземпляре NSString, предоставленном моим преобразователем. Мне это кажется большой дырой в Core Data, поскольку я уверен, что существует бесчисленное множество нестандартных типов, которые можно хранить и запрашивать как строковые атрибуты.

Кажется, единственный вариант, помимо использования NSString, - это сделать, как описывает @Alex, и использовать переходные свойства и производные значения. Однако Core Data не делает это очень чистым, потому что, как заявил @Alex, невозможно обеспечить исключительное использование средств доступа к временным свойствам.

person Robert St. John    schedule 30.06.2017