Objective-C Custom Getter / Setter

I am using the following NSManagedObject, which was automatically generated by Xcode:

@interface Portion :  NSManagedObject  
{
}

@property (nonatomic, retain) NSNumber * volume;

I would like to create a custom getter / setter to convert between ml / oz depending on what the user has installed, so the database always saves the same value and automatically converts to preferred units. My last attempt looks like this:

#import "Portion.h"
#import "SettingHandler.h"

#define MILLILITERS_PER_OUNCE 29.5735296

@implementation Portion 

@dynamic volume;

- (void) setVolume:(NSNumber *) number {
    if ([SettingHandler getUnitsTypeShort] == @"oz") {
        [self setValue:number forKey:@"volume"];
    } else {
        [self setValue:[NSNumber numberWithFloat:[number floatValue] * MILLILITERS_PER_OUNCE] forKey:@"volume"];
    }
}

- (NSNumber *) volume {
    if ([SettingHandler getUnitsTypeShort] == @"oz") {
        return [self valueForKey:@"volume"];
    } else {
        return [NSNumber numberWithDouble: [[self valueForKey:@"volume"] floatValue] * MILLILITERS_PER_OUNCE];
    }
}

The setVolume call ends the call, causing an infinite loop. I guess there is a way to do this, but I don’t know what it is, any ideas?

+3
source share
4 answers

" -" . , getter/setter / KVO.

:

@interface Portion (PrimitiveAccessors)
- (NSNumber *)primitiveVolume;
- (void)setPrimitiveVolume:(NSNumber *)number; 
@end

:

[self setValue:number forKey:@"volume"];

:

[self willChangeValueForKey:@"volume"];
[self setPrimitiveVolume:number];
[self didChangeValueForKey:@"volume"];

.

+7

, , IMO, , , ( , . Model-View-Controller). , , NSNumber , ​​?

, , , . "unitsType", , .

, , MDFileSizeFormatter, :

#import <Foundation/Foundation.h>

enum {
    MDVolumeFormatterMetricUnitsType            = 1,
    MDVolumeFormatterOurStupidAmericanUnitsType = 2,
    MDVolumeFormatterDefaultUnitsType = MDVolumeFormatterMetricUnitsType
};

typedef NSUInteger MDVolumeFormatterUnitsType;


@interface MDVolumeFormatter : NSFormatter {
    MDVolumeFormatterUnitsType    unitsType;
    NSNumberFormatter            *numberFormatter;
}
- (id)initWithUnitsType:(MDVolumeFormatterUnitsType)aUnitsType;

@property (assign) MDVolumeFormatterUnitsType unitsType;

@end

.m:

#import "MDVolumeFormatter.h"

#define MILLILITERS_PER_OUNCE 29.5735296

@implementation MDVolumeFormatter

@synthesize unitsType;

- (id)init {
    return [self initWithUnitsType:MDVolumeFormatterDefaultUnitsType];
}

- (id)initWithUnitsType:(MDVolumeFormatterUnitsType)aUnitsType {
    if (self = [super init]) {
        numberFormatter = [[NSNumberFormatter alloc] init];
        [numberFormatter setFormat:@"#,###.#"];
        [self setUnitsType:aUnitsType];
    }
    return self;
}

- (void)dealloc {
    [numberFormatter release];
    [super dealloc];
}

- (NSString *)stringForObjectValue:(id)anObject {
    if ([anObject isKindOfClass:[NSNumber class]]) {
        NSString *string = nil;
        if (unitsType == MDVolumeFormatterMetricUnitsType) {
            string = [[numberFormatter stringForObjectValue:
                       [NSNumber numberWithFloat:
                        [(NSNumber *)anObject floatValue] * MILLILITERS_PER_OUNCE]]
                      stringByAppendingString:@" mL"];

        } else {
            string = [[numberFormatter stringForObjectValue:anObject] stringByAppendingString:@" oz"];
        }
        return string;
    }
    return nil;
}

@end

. , floatValue 16.0, , "2.0 " 16 .

+8

[self setPrimitiveValue:number forKey:@"volume"];.

+2

. - . , . /:

- (void) setOunces:(double)ounces;
- (double) ounces;

- (void) setMilliliters:(double)milliliters;
- (double*) milliliters;

, :

- (void) setOunces:(double)ounces
{
[self setVolume:[NSNumber numberWithDouble:(ounces* MILLILITERS_PER_OUNCE)]];
}

- (double) ounces
{
return [[self volume] doubleValue]/MILLILITERS_PER_OUNCE;
}

- (void) setMilliliters:(double)milliliters
{
[self setVolume:[NSNumber numberWithDouble:milliliters]];
}

- (double) milliliters
{
return [[self volume] doubleValue];
}
+2

Source: https://habr.com/ru/post/1774007/


All Articles