Как сохранить виртуальное свойство 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;
}