1

コア データを使用して、いくつかの配列を文字列として格納します。文字列には、STRINGFROMARRAY というプレフィックスが付けられ、&,& で区切られます。

アクセスが必要になるたびに変換するコードを提供する必要がないように、セッターとゲッターをオーバーライドするのはいいことだと思いました。「memberIds」(文字列) という 1 つの属性のみを持つ TestEntity という管理オブジェクト サブクラスを作成しました。カスタム セッターとゲッターが正常に動作しているように見えることを確認しました。

TestEntity.h:

@interface TestEntity (CoreDataGeneratedAccessors)

- (NSArray*)memberIds;
- (void)setMemberIds:(NSArray *)memberIds;

@end

TestEntity.m:

@implementation TestEntity

@dynamic memberIds;

- (NSArray *)memberIds
{
    [self willAccessValueForKey:@"memberIds"];
    NSArray *memberIdsArray = [NSArray arrayWithArray:[[[self primitiveValueForKey:@"memberIds"] substringFromIndex:15] componentsSeparatedByString:@"&,&"]];
    [self didAccessValueForKey:@"memberIds"];
    return memberIdsArray;
}

- (void)setMemberIds:(NSArray *)memberIds
{
    NSString *stringFromArray = [@"STRINGFROMARRAY" stringByAppendingString:[memberIds componentsJoinedByString:@"&,&"]];
    [self willChangeValueForKey:@"memberIds"];
    [self setPrimitiveValue:stringFromArray forKey:@"memberIds"];
    [self didChangeValueForKey:@"memberIds"];
}

@end

配列値を設定でき、文字列として適切に保存されます。valueForKey設定後に値をログに記録するために使用することもでき、配列として適切に出力されます。

ただし、マネージド オブジェクト全体(valueForKey: なし)をログに記録しようとすると、[NSArray length] 認識されないセレクター エラーが発生します。

これをテストするために使用しているコードは次のとおりです。

NSManagedObject *test = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity" inManagedObjectContext:[SyncEngine sharedEngine].managedObjectContext];
[test setValue:[NSArray arrayWithObjects:@"1", @"2", @"3", nil] forKey:@"memberIds"];
NSLog(@"%@", [test valueForKey:@"memberIds"]);
NSLog(@"%@", test);

出力は次のとおりです。

2013-08-24 13:59:27.820 0.1[1440:19d03] (
    1,
    2,
    3
)
2013-08-24 13:59:27.820 0.1[1440:19d03] -[__NSArrayI length]: unrecognized selector sent to instance 0xa533800

lengthメッセージがアレイに送信されるのはなぜですか? そして、どうすればこのクラッシュを防ぐことができますか? ありがとう!

4

1 に答える 1

2

問題は、memberIds メソッドをオーバーライドしたことだと思います。

モデルでは、memberIds は文字列を返す必要があり、それをオーバーライドして NSArray を返します。そのため、managedobjet がその説明を生成しようとするとき、memberIds が文字列であると想定しています。

カスタムゲッター/セッターにモデル属性とは異なる名前を付けるのが最善の方法だと思います。

于 2013-08-24T18:37:48.490 に答える