Make Custom Struct Key-Value Coding Compliant

  • Core Data Question

    I have a custom struct that I would like to make key-value coding compliant so it will work with Core Data as a non-standard persistent attribute. Is it possible to make a custom struct key-value coding compliant?

    I would rather not store it in the managed object as an object but would like to leave it as a struct and have it work just like NSPoint, NSSize, NSRect, or NSRange.

    Core Data Programming Guide
    Non-Standard Persistent Attributes
    Scalar Value Constraints

    "A requirement of the accessor methods you write is that they must be key-value coding (and key-value observing) compliant. Key-value coding only supports a limited number of structures—NSPoint, NSSize, NSRect, and NSRange."

    "If you want to use a scalar type or structure that is not one of those supported directly by Core Data and not one of the structures supported by key-value coding, you must store it in your managed object as an object-typically an NSValue instance, although you can also define your own custom class. You will then treat it as an object value as described later in this article. It is up to users of the object to extract the required structure from the NSValue (or custom) object when retrieving the value, and to transform a structure into an NSValue (or custom) object when setting the value."

    --Richard
  • On 12/02/2012, at 5:43 PM, Richard Somers wrote:

    > I would rather not store it in the managed object as an object but would like to leave it as a struct and have it work just like NSPoint, NSSize, NSRect, or NSRange.

    May one ask why?

    The section of the documentation you posted spells out pretty clearly that what you want to do is not supported, you either have to make it an object or wrap it in NSValue.

    Making it an object is easy and usually it turns out that the desire to resist doing that is misguided, based on some faulty assumptions. What are yours? If you need a scalar struct to pass to external code, just declare a method that will return that on demand, and a class method to make the object from the struct. Then any necessary conversion is also super-simple.

    --Graham
  • On Feb 11, 2012, at 10:56 PM, Graham Cox <graham.cox...> wrote:

    > Making it an object is easy and usually it turns out that the desire to resist doing that is misguided, based on some faulty assumptions. What are yours? If you need a scalar struct to pass to external code, just declare a method that will return that on demand, and a class method to make the object from the struct. Then any necessary conversion is also super-simple.

    Also, as we transition toward ARC, we will need to switch to objects instead of structs containing pointers to objects. So it's better to just get in the habit of using objects throughout, whether it's NSDictionaries or custom NSObject subclasses.

    --Kyle Sluder
  • On Feb 11, 2012, at 11:56 PM, Graham Cox wrote:

    > Making it an object is easy and usually it turns out that the desire to resist doing that is misguided, based on some faulty assumptions. What are yours?

    Geometry objects are slow which is why Cocoa has the likes of NSPoint, NSSize, and NSRect.

    If I use an object then each managed object attribute would look something like this.

        1. Persistent Attribute (NSString so it is readable in the XML store)

        2. Transient Shadow Attribute (must be an object)

        3. Struct Obtained from the Shadow Attribute

    It just seems so heavy. My app will be using the scalar accessors very frequently.

    Karoly Lorentey has a blog entry "Efficient Scalar Attributes in Core Data" for iOS. I was trying to follow his lead except target Mac OS X v10.6 using a struct instead of a single scalar but it has been rough going.

        http://blog.lorentey.hu/2010/10/31/core-data-scalars/

    On Feb 12, 2012, at 12:18 AM, Kyle Sluder wrote:

    > Also, as we transition toward ARC, we will need to switch to objects instead of structs containing pointers to objects. So it's better to just get in the habit of using objects throughout, whether it's NSDictionaries or custom NSObject subclasses.

    My struct contains no pointers.

    --Richard
  • On Sat, Feb 11, 2012 at 11:40 PM, Richard Somers <rsomers123...> wrote:
    > Karoly Lorentey has a blog entry "Efficient Scalar Attributes in Core Data" for iOS. I was trying to follow his lead except target Mac OS X v10.6 using a struct instead of a single scalar but it has been rough going.
    >
    >     http://blog.lorentey.hu/2010/10/31/core-data-scalars/

    Hmm. The Foundation Release Notes for 10.5 indicate that KVC supports
    arbitrary structs (see section titled "Support for Arbitrary Types in
    KVC and KVO"): https://developer.apple.com/library/mac/#releasenotes/Cocoa/FoundationOlder
    .html#//apple_ref/doc/uid/TP40008080


    But the blog you linked to indicates that manually-implemented
    accessors aren't exactly the most efficient.

    --Kyle Sluder
  • On Feb 12, 2012, at 1:28 AM, Kyle Sluder wrote:

    > Hmm. The Foundation Release Notes for 10.5 indicate that KVC supports arbitrary structs (see section titled "Support for Arbitrary Types in KVC and KVO")

    Yes I have read that several times. It seems to be at odds with the Core Data documentation. It is very confusing.

    I have not been able to get custom structs to work properly with Core Data. So for now I would agree with the Core Data documentation that they are somehow not KVC compliant.

    > But the blog you linked to indicates that manually-implemented accessors aren't exactly the most efficient.

    If you read all the way to the bottom of the blog, he was able to substantially improve the results with manually-implemented scalar accessors.

    Another confusing thing is that Xcode 4.2 has a new undocumented checkbox called "Use scalar properties" in the class generation sheet. But this only works with iOS 5 and Mac OS X 10.7.

        http://subjectiveobserver.wordpress.com/

    --Richard
  • On 12 feb 2012, at 01:04, Richard Somers wrote:

    >> Hmm. The Foundation Release Notes for 10.5 indicate that KVC supports arbitrary structs (see section titled "Support for Arbitrary Types in KVC and KVO")
    >
    > Yes I have read that several times. It seems to be at odds with the Core Data documentation. It is very confusing.

    Please file a bug report on the documentation:

    <http://developer.apple.com/bugreporter/>

    Joar
  • On 12 Feb 2012, at 1:04 am, Richard Somers wrote:

    > Another confusing thing is that Xcode 4.2 has a new undocumented checkbox called "Use scalar properties" in the class generation sheet. But this only works with iOS 5 and Mac OS X 10.7.

    I can testify (after some frustrating time tracking it down) that NSManagedObject subclasses with properties declared in this way--while compiling without incident--throw exceptions when called under 10.6.8.

    b

    --
    Ben Kennedy, chief magician
    Zygoat Creative Technical Services
    http://www.zygoat.ca
  • On 12/02/2012, at 6:40 PM, Richard Somers wrote:

    > It just seems so heavy. My app will be using the scalar accessors very frequently.

    Seems. But is it?

    There's no reason I can think of that this couldn't be efficient, using caching as necessary and so on.

    If the ultimate goal is to render something - you mention a shadow but it's not clear if that's a graphical shadow effect - the rendering will utterly dominate. Especially in Quartz where shadows are the slowest thing on earth.

    --Graham
  • SOLVED - Thanks for all the comments.

    On Feb 11, 2012, at 11:56 PM, Graham Cox wrote:

    > Making it an object is easy and usually it turns out that the desire to resist doing that is misguided, based on some faulty assumptions.

    I decided to resist no longer and make my custom strut an object. I made an object that had individual properties corresponding to the struct members. Unfortunately this created to many problems elsewhere.

    But the story has a happy ending. Arbitrary structs are Key-Value Coding compliant and work fine with Core Data, they do not need to be stored in the managed object as an object. The documentation is in error on this point.

    On Feb 12, 2012, at 2:18 AM, Joar Wingfors wrote:

    > Please file a bug report on the documentation:

    Filed bug report Bug ID# 10872122.

    On Feb 12, 2012, at 6:50 AM, John Joyce wrote:

    > But the best advice, don't fight the framework.

    Agreed. Originally I thought that custom structs were not compatible with Core Data. But this is not true. They can work very well with the framework.

    Thanks again.

    --Richard
previous month february 2012 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29        
Go to today