Есть ли обратный "setValuesForKeysWithDictionary" - makeDictionaryWithObjectProperties?

Я разбираю некоторые JSON из веб-службы, это дает мне NSDictionary, я использую этот словарь для заполненных свойств в valueEntity типа NSObject с помощью

[myObject setValuesForKeysWithDictionary:JSONDict];

(myObject имеет те же имена и типы свойств, что и словарь из анализатора JSON)

name = name
count = count
startDate = startDate
etc..

Есть ли способ пойти другим путем, где у меня есть NSDictionary, который я бы хотел "заполнить" свойствами и их значениями из моего подкласса NSObject. Как я предлагаю в названии, что-то вроде этого:

в одну сторону

MyObject *myObject = [[MyObject alloc] init];
[myObject setValuesForKeysWithDictionary:JSONDict];

наоборот

NSMutableDictionary *dict = [myObject makeDictionaryWithObjectProperties];

Причиной этого является то, что у меня есть значениеEntity, которое по протоколу соответствует моим представлениям, но я хотел бы также заполнить NSManagedObject значениями. Поэтому я подумал, что используя NSDictionary как промежуточный шаг, я могу обойтись, чтобы сделать категорию в моем NSManagedObject, который устанавливает каждое свойство вручную из значения объекта my подкласса NSObject.

Со словарем я могу пойти:

[myManagedObject setValuesForKeysWithDictionary:dict];

Я просто не могу получить представление словаря назад после того, как сделал это выше?

Ответы

Ответ 1

Да, метод:

- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys

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

Протокол NSKeyValueCoding определяет ряд мощных и очень полезных методов; это здорово познакомиться.

http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html

Там также очень ценный справочник компаньона:

http://developer.apple.com/library/ios/documentation/cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html#//apple_ref/doc/uid/10000107i

Ответ 2

Вы действительно хотите получить все свойства? Часто не имеет смысла получить все свойства объекта в качестве словаря. Например, если NSManagedObject содержит отношения, вы хотите получить его в словаре? Если да, как вы хотите это представить?

Как сказал jlehr, лучше всего использовать набор ключей, используя dictionaryWithValuesForKeys:.

Тем не менее, используя страшное время выполнения Objective-C, вы действительно можете реализовать makeDictionaryWithObjectProperties. Используйте class_getPropertyList и property_getName. Я не буду подробно описывать, как это сделать, потому что, если вы будете следовать этому подходу, вы знаете, что делаете.

Кстати, очень опасно назначать объект JSON, возвращенный из Интернета, на NSManagedObject с помощью setValuesForKeysWithDictionary:. Потому что, если объект JSON содержит дополнительный ключ, которого вы не ожидаете, ваш код может внезапно сработать. Итак, не делайте этого.

Еще один комментарий: ваш псевдокод

NSObject *myObject = [[NSObject alloc] init];
[myObject setValuesForKeysWithDictionary:JSONDict];

не имеет большого смысла: да, вы можете вызвать setValuesForKeysWithDictionary: против NSObject, но он будет терпеть неудачу, потому что вы не можете setValue:forKey: для любой из записей в JSONDict использовать ваниль NSObject. Наверное, вы знаете это, но я бы хотел сказать это явно, чтобы новичок, который сталкивался с этой страницей, не обманул.

Ответ 3

Этот парень здесь использовал некоторую магию времени выполнения, чтобы получить все свойства, объявленные на объекте, и получил словарь без ручного предоставления имен свойств.

И вот этот хороший github repo я нашел, они в значительной степени делают тот же трюк, но в хорошем пакете. Они также имеют возможность создавать json или plist из объекта.