web-dev-qa-db-ja.com

NSManagedObjectサブクラスの@dynamicプロパティのゲッターとセッターをオーバーライドすることは可能ですか?

だから、私のシナリオはこれです:

IOSアプリケーションにNSManagedObjectサブクラスがあり、プロパティとしてMKPolygonオブジェクトのコンテンツを保存したいと思います。これについて私が決めた方法(そしてそれが有効かどうかはおそらく別の質問です)は、ポリゴンプロパティを変換可能なオブジェクトとして宣言し、ポリゴンのポイントを含むNSArrayを(NSValueオブジェクトとして)格納することです。

この目的のために、モデルオブジェクトにいくつかの便利なクラスメソッドを記述しました。

+ (NSArray *)coordsArrayFromMKPolygon:(MKPolygon *)polygon pointCount:(int)count
{
    CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(sizeof(CLLocationCoordinate2D) * count);
    [polygon getCoordinates:coords range:NSMakeRange(0, count)];
    NSMutableArray *coordsArray = [NSMutableArray array];
    for (int i = 0; i < count; i++) {
        NSValue *coordVal = [NSValue valueWithBytes:&coords[i] objCType:@encode(CLLocationCoordinate2D)];
        [coordsArray addObject:coordVal];
    }
    free(coords);
    return [NSArray arrayWithArray:coordsArray];
}

+ (MKPolygon *)polygonFromCoordsArray:(NSArray *)coordsArray pointCount:(int)count
{
    CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(sizeof(CLLocationCoordinate2D) * count);
    for (int i = 0; i < count; i++) {
        CLLocationCoordinate2D coord;
        [[coordsArray objectAtIndex:i] getValue:&coord];
        coords[i] = coord;
    }
    free(coords);
    return [MKPolygon polygonWithCoordinates:coords count:count];
}

モデルのインスタンスを保存またはロードする前に、MKPolygonオブジェクトでこれらのメソッドを呼び出すことができますが、モデル自体の動的ゲッターとセッターをオーバーライドして、[turf setTurf_bounds:polygon]のように言うことができます。 (ポリゴンはMKPolygonインスタンスです)。

私が本当に望んでいるのは、次のようなことができるようにすることです。

- (void)setTurf_bounds:(id)turf_bounds
{
    MKPolygon *poly = (MKPolygon *)turf_bounds;
    NSArray *coordsArray = [Turf coordsArrayFromMKPolygon:poly pointCount:[poly pointCount]];
    // Save the converted value into the @dynamic turf_bounds property
}

- (id)turf_bounds
{
    // grab the contents of the @dynamic turf_bounds property into say, NSArray *coordsArray
    return [Turf polygonFromCoordsArray:coordsArray pointCount:[coordsArray count]];
}

しかし、私は今のところ喜びがありませんでした。 [super setValue:coordsArray forKey:@"turf_bounds"]またはそれに対応するゲッターを呼び出すことは機能せず、self.turf_bounds(オーバーライドされたセッターを再帰的に呼び出すだけ)として書き込もうとすることもありません。

私はこれを完全に間違った方法で行っているのですか、それとも単に何かが足りないのですか?

39
HowlingEverett

NSManagedObjectサブクラスで[supervalueForKey:..]を呼び出さないでください。 (自分でスーパークラスに実装した場合を除きます)代わりに、プリミティブアクセサーメソッドを使用します。

[〜#〜] adc [〜#〜] からのサンプルゲッター/セッター実装:

@interface Department : NSManagedObject
@property(nonatomic, strong) NSString *name;
@end

@interface Department (PrimitiveAccessors)
- (NSString *)primitiveName;
- (void)setPrimitiveName:(NSString *)newName;
@end


@implementation Department

@dynamic name;

- (NSString *)name
{
    [self willAccessValueForKey:@"name"];
    NSString *myName = [self primitiveName];
    [self didAccessValueForKey:@"name"];
    return myName;
}

- (void)setName:(NSString *)newName
{
    [self willChangeValueForKey:@"name"];
    [self setPrimitiveName:newName];
    [self didChangeValueForKey:@"name"];
}

@end
76
Martin Brugger