On 29 Aug 2014, at 3:20 pm, Quincey Morris 
<quinceymor...@rivergatesoftware.com> wrote:

> {<struct-tag-name>=…
> 
> which you can use to figure out what you need.


This is much what I'm doing, but it's a bit simpler - I don't need to 
introspect the property details of the target object, since I know that 
-valueForKey: will return scalar types wrapped in an NSValue. NSValue has 
-objCType, which for a struct returns {name=...}, e.g. {CGSize=dd}.

I already know that a given property of a given object is a CGSize (say), so 
for those properties I set through my 'unwrapper' method which uses the 
following code in a category on NSValue to do the work:

        
        const char* typ = [self objCType];
        NSString* typeString = [NSString stringWithCString:typ 
encoding:NSASCIIStringEncoding];
        
        // split out point, size and rect structs (others not supported at 
present)
        
        if([typeString rangeOfString:@"{CGPoint"].location == 0)
        {
                // it's a point
                
                NSPoint p = [self pointValue];
                
                if([fieldName isEqualToString:@"x"])
                        p.x = v;
                else if([fieldName isEqualToString:@"y"])
                        p.y = v;
                
                return [NSValue valueWithPoint:p];
        }
        else if([typeString rangeOfString:@"{CGSize"].location == 0)
        {
                // it's a size
                
                NSSize s = [self sizeValue];
                
                if([fieldName isEqualToString:@"width"])
                        s.width = v;
                else if ([fieldName isEqualToString:@"height"])
                        s.height = v;
                
                return [NSValue valueWithSize:s];
        }
        else if([typeString rangeOfString:@"{CGRect"].location == 0)
        {
                ... more


This isn't general, but it covers the common cases of Points, Sizes and Rects, 
which is all I need at present.

The higher level "unwrapper" splits up the keypath name so that the last 
component is the struct field name, which it passes into this code. The NSValue 
itself is returned by -valueForKeypath: on the target object using the rest of 
the path (i.e. the last component is removed). For specific objects this could 
be done in an override of -setValueForKeyPath, but I'm actually implementing 
this in the controller rather than try and subvert the more general KVC 
mechanics - seems a bit safer that way.

Works nicely for my use case :)

--Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to