3

I like the plist serialization capability for small collections of objects: it is simple, the storage is XML, etc. But I find setting values in dictionaries cumbersome:

[myDict setObject:keepThis forKey:@"ivar"];

I'd much prefer to use object derived of classes (or even just structs):

myObj.ivar = keepThis

... and then send a message to a collection to get a plist. The classes/structs used for this purpose could be restricted so that they map directly and easily to plist primitives; for example myObj could be mapped to a NSDictionary and a requirement could be placed on ivars such that they are one of the plist primitives.

Has someone already built a facility for this, or should I roll my own?

jeff7091
  • 957
  • 2
  • 13
  • 25

5 Answers5

5

I'm not sure that this is quite what you're talking about, but Key Value Coding will, among many other things, let you get a dictionary with values from an instance's data, and also set instance data from a dictionary.

There's also a way to ask an instance for a list of its attributes, though it turns out that you have to write some code yourself to make that work. (You, could, though, use the runtime introspection to implement that, if you wanted.) EDIT 2 January 2011: -[NSObject attributeKeys] no longer appears in the iOS documentation. I've edited the link to point to the Mac documentation, but be aware that this may only be an option on that platform.

(The NSCoding protocol is another way of letting your objects store/restore themselves, but the storage is binary, not XML, and you are still responsible for getting/putting each value you care about when asked by the system to do so.)

Sixten Otto
  • 14,816
  • 3
  • 48
  • 60
  • Another thing to keep in mind is that property list serialization kills the identity of the object(s) you serialize. If you need to maintain that identity, use `NSCoding` with `NSKeyedArchiver`, etc. – Marc W Oct 30 '09 at 21:51
  • But ... to "get a dictionary with values from an instance's data", you need to have an object that implements the informal protocol NSKeyValueCoding. For example, NSManagedObject does not implement this message of that protocol. So again, one is back to runtime introspection, or perhaps using the entity class of Core Data to pick the object apart. Also, NSCoding seems very manual, in that for every property you add to a class, you then need to go and edit the encoder and decoder - even when the en/decoders are keyed! So it looks like such a framework is just not out there... – jeff7091 Nov 17 '09 at 08:51
  • `NSManagedObject` definitely implements `-dictionaryWithKeysForValues:`. In general, Core Data builds extensively on Key-Value Coding and Key-Value Observing to do its work. – Sixten Otto Nov 17 '09 at 17:30
  • Do you mean -committedValuesForKeys: ? – jeff7091 Nov 20 '09 at 23:56
  • No, I mean `-dictionaryWithKeysForValues:`, the KVC method I linked to in my answer, and that you said in your earlier comment `NSManagedObject` doesn't implement. It does (along with much more of KVC and KVO). – Sixten Otto Nov 21 '09 at 01:53
  • No, you mean dictionaryWithValuesForKeys :-) – jeff7091 Nov 22 '09 at 06:53
  • OK, you got me that time. :-) – Sixten Otto Nov 22 '09 at 15:42
  • The links appear to be broken now - I think Apple re-arranged their docs, and didn't bother to preserve the links. New versions are http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html#//apple_ref/doc/uid/20000471-BABIAGCF and http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html#//apple_ref/doc/uid/20000471-BABBIHEB (sorry, SO is too dumb to allow comments to have formatting :( :( :( ) – Adam Dec 25 '10 at 16:55
3

You might want to check out this SO question which discusses putting an instance's ivars in a dictionary at runtime.

Community
  • 1
  • 1
nall
  • 15,899
  • 4
  • 61
  • 65
2

An interesting project. The Objective-C 2.0 Programming Guide has a section on the runtime functions to dynamically get a list of a class's properties:

objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)

With this, it should be quite easy to write a category on NSObject with a method that gets the list of properties and puts them into a dictionary.

Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • The SO question that nall links ( http://stackoverflow.com/questions/1631358/is-there-a-way-to-dynamically-determine-ivars-of-a-class-at-runtime-in-cocoa-co/1631611#1631611 ) to contains code that provides the same end result. – Alex Reynolds Oct 30 '09 at 23:02
0

In order to use properties for this, you would need to have a predefined set of possible keys. You can't use arbitrary names with the dot-syntax — it had to be a known property or accessor of the first operand. So there can't be a generic form of this. But if you do make one of your own, turning into a dictionary is as simple as doing [self dictionaryWithValuesForKeys:listOfProperties].

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • As Ole Begemann pointed out, you can ask the runtime for a list of the properties for a class. NSObject also defines attributeKeys (though you do have to write the NSClassDescription that powers that, ultimately). – Sixten Otto Oct 30 '09 at 23:10
0

I saw this posted elsewhere, but it is exactly what I was looking for. The answers above point to the raw ingredients, but here it is, all wrapped-up: http://retaincount.com/blog/?p=7

jeff7091
  • 957
  • 2
  • 13
  • 25
  • So, just to be clear, if this is your answer now. KVC (and `-dictionaryWithValuesForKeys:`) *does* work on these objects? Since that's a big part of how this linked solution works.... – Sixten Otto Nov 21 '09 at 13:48
  • Before I found this link, I wrote something that would work with CD. I ended up sending -attributesByName to the entity associated with the NSManagedObject instance; it works fine. As I had to write something (and it works), I haven't gone over to this package. But I will look at it for then next project. – jeff7091 Nov 22 '09 at 07:00