Как сохранить виртуальное свойство Core Data?

У меня есть подкласс NSManagedObject с виртуальным свойством, которое дорого рассчитывать. Свойство зависит от значения одного из конкретных атрибутов объекта. По соображениям производительности я хочу вычислять значение виртуального свойства только тогда, когда свойство, от которого оно зависит, изменяется.

Я замечаю, что метод доступа к моей виртуальной собственности (дорогой) вызывается КАЖДЫЙ раз при доступе к значению. Каков наилучший способ сохранить расчетную стоимость виртуальной собственности? Есть ли какая-то встроенная часть KVC, которая позволяет мне кэшировать вычисленное значение?

Интерфейс:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface CDUserPhotos : NSManagedObject

// Core Data attribute
@property (nonatomic, retain) NSData * data;

// Virtual property
@property (readonly) NSArray* photos;

// Changes the value of 'data' property
- (void)refresh;

@end

Реализация:

#import "CDUserPhotos.h"

@implementation CDUserPhotos

// Core data attributes
@dynamic data;

#pragma mark -
#pragma mark Public

+ (NSSet *)keyPathsForValuesAffectingPhotos
{
    NSSet* set = [NSMutableSet setWithObjects:@"data", nil];
    return set;
}

#pragma mark -

- (NSArray *)photos
{
    if ( self.data )
    {
        return [self.data expensiveCalculation];    // We want to prevent calls to this method!
    }
    return nil;
}

- (void)refresh
{
    // some code deleted here. Basically, the value of self.data changes which therefore changes the value of self.photos.
    self.data = [self newData]; // not shown
}

@end

Какой-то другой код

// self.albums.photos is an object of CDUserPhotos (NSManagedObject)
j = self.albums.photos.count;       // triggers expensive calculation
k = self.albums.photos.count;       // should not trigger expensive calculation

[self.albums refresh];

q = self.albums.photos.count;       // triggers expensive calculation

1 ответ

Это может быть что-то простое, как:

if (self.data) {
    if(!_photos) {
        _photos = [self.data expensiveCalculation];
    }
    return _photos;
} else {
    return nil;
}

и вам также придется:

- (void)refresh
{
    self.data = [self newData]; // not shown
    _photos = nil;
}
Другие вопросы по тегам