KVC Collection Operators on primitive values

447 views Asked by At

Can collection operators be used on primitive values?

I have an object that has a primitive property duration.

@property (nonatomic) NSTimeInterval duration;

I have an NSArray of those said objects and I would like to use a collection operation on the array to get the sum of the durations. The problem is that @"@sum.duration" expects an NSNumber instead.

Will I have to do this the old fashioned way, or is there a way to use primitives?

2

There are 2 answers

6
Martin R On BEST ANSWER

From "Scalar and Structure Support" in the "Key-Value Coding Programming Guide":

Key-value coding provides support for scalar values and data structures by automatically wrapping and unwrapping NSNumber and NSValue instance values.

So

NSNumber *sum = [array valueForKeyPath:@"@sum.duration"];

just works, even if duration is a scalar property. Small self-contained example:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
@property(nonatomic, assign) NSTimeInterval duration;
@end

@implementation MyClass
@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyClass *obj1 = [MyClass new];
        obj1.duration = 123.4;
        MyClass *obj2 = [MyClass new];
        obj2.duration = 456.7;
        NSArray *array = @[obj1, obj2];

        NSNumber *sum = [array valueForKeyPath:@"@sum.duration"];
        NSLog(@"sum = %@", sum);
    }
    return 0;
}

Output: 580.1.

1
godel9 On

You can always add another property:

@property (nonatomic) NSNumber *durationNumber;

and implement both the getter and setter:

- (NSNumber *)durationNumber {
    return [NSNumber numberWithDouble:self.duration];
}

- (void)setDurationNumber:(NSNumber *)durationNumber {
    self.duration = durationNumber.doubleValue;
}

Implementing both the setter and getter inhibits automatic synthesis of the backing ivar.