6

デバイス間で単一のオブジェクトを転送する必要があります。現在、NSManagedObject を Dictionary に変換し、アーカイブして NSData として送信しています。受け取り次第、アーカイブを解除します。しかし、中間データ オブジェクトを作成する代わりに、アーカイブとアーカイブ解除によって NSManagedObject 自体を転送したいと考えています。

@interface Test : NSManagedObject<NSCoding>
@property (nonatomic, retain) NSString * title;
@end

@implementation Test
@dynamic title;

- (id)initWithCoder:(NSCoder *)coder {
    self = [super init];
    if (self) {
        self.title = [coder decodeObjectForKey:@"title"]; //<CRASH
    }
    return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.title forKey:@"title"];
}
@end


NSData *archivedObjects = [NSKeyedArchiver archivedDataWithRootObject:testObj];
NSData *objectsData = archivedObjects;
if ([objectsData length] > 0) {
    NSArray *objects = [NSKeyedUnarchiver unarchiveObjectWithData:objectsData];
}

上記のコードの問題は. インスタンスに認識されないセレクターが送信されたと言っself.titleてクラッシュします。initWithCoder

  • titleがセレクターとして認識されないのはなぜですか。
  • でオブジェクトを作成する前に、どういうわけか nil 管理オブジェクト コンテキストを unarchive する必要がありますinitWithCoderか?
  • オーバーライドする必要がありますcopyWithZoneか?
4

3 に答える 3

1

には明らかにNSManagedObject準拠していませんNSCoding。カスタム管理対象オブジェクトのサブクラスを適合させようとすることもできますが、それはせいぜい危険な提案です。NSManagedObjectには関連するが必要NSManagedObjectIDです。また、オブジェクト ID を割り当てる必要はありません。これは、オブジェクトの作成時に自動的に行われます。サブクラスを に準拠させたNSCodingとしても、ローカルの管理対象オブジェクト コンテキストがオブジェクト ID を割り当てられるようにしながら、オブジェクトをアーカイブ解除する方法を見つける必要があります。

それでも、管理対象オブジェクトの関係をどのように処理するかという問題は無視されます。

への/からの変換NSDictionaryは、実際にははるかに優れたアプローチです。ただし、データを解凍して終了することはできません。受信側では、新しい管理オブジェクト インスタンスを作成し、ディクショナリからその属性値を設定する必要があります。アプローチを機能させることは可能かもしれませんが、完了するまでにはNSDictionary .

真剣に: NSCodinginitWithCoder:copyWithZone:などは、解決しようとしている問題にとって本当に悪い考えです。NSCoding多くの状況に適していますが、ここでは適切ではありません。

于 2013-05-08T16:42:16.930 に答える