2009-02-01 40 views
17

想象一下CoreData实体(例如名为searchEngine)。
NSManagedObjectContext管理此实体的一些“实例”。
最终用户将能够选择他的"standard searchEngine"NSPopupButton
NSPopupButton的selected object应绑定到NSUserDefaults。
问题:将核心数据实体保存在NSUserDefaults中

1) @try {}保存

a)如果您尝试将直接选择 “实例” 保存到那里NSUserDefaults的说到这样的事情:

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value ' (entity: searchEngine; id: 0x156f60 ; data: { 
    url = " http://google.de/ "; 
    someAttribute = 1; 
    name = "google"; 
})' of class 'searchEngine'.

b)如果您尝试将“实例”转换为NSData这个:

-[searchEngine encodeWithCoder:]: unrecognized selector sent to instance 0x1a25b0

所以任何想法如何获得这个实体在plist兼容的数据?

2) @try {registerDefaults}

通常registerDefaults:方法在+ (void)initialize实现。这里的问题是在CoreData从他的数据库加载保存的实体之前调用这个方法。所以我不能将默认设置为不存在的对象,对吧?

我知道,长期的问题... ...但:尝试{[我提供:详细信息]}; d

回答

6

你不会想尝试和存档核心数据实体并将其存储。相反,您应该存储密钥或其他已知属性,并在应用程序启动时使用它来获取实体。

一些示例代码(略从张贴在Core Data Programming Guide的例子修改):

NSManagedObjectContext *moc = [self managedObjectContext]; 
NSEntityDescription *entityDescription = [NSEntityDescription 
    entityForName:@"SearchEngine" inManagedObjectContext:moc]; 
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
[request setEntity:entityDescription]; 

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
    @"engineName LIKE[c] '%@'", selectedEngineName]; 
[request setPredicate:predicate]; 

NSError *error = nil; 
NSArray *array = [moc executeFetchRequest:request error:&error]; 
if (array == nil) 
{ 
    // Deal with error... 
} 

这样你在用户默认保存的名称,必要时取的实体。

+0

Mmh的。你知道为什么`array!= nil`但是[array count] <0` ...它不想工作... – papr 2009-02-04 20:12:07

+0

如果array!= nil那么没有错误,但也可能没有记录返回([数组计数] == 0)...但是,由于计数消息返回NSUInteger类型,[数组计数] <0可能不会发生。编译器很可能会剥夺任何此类测试([数组数量] <0)。 – 2009-02-04 20:33:44

33

如果你需要存储到特定管理对象的引用,使用它的管理对象ID的URI表示:

NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation]; 

然后,您可以保存URL到用户的默认值。

要检索的管理对象,请使用:

NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL]; 
NSManagedObject *myManagedObject = [myContext objectWithID:moID]; 

唯一需要注意的是,你必须保证原有管理对象ID是永久的 - 这不是一个问题,如果你已经保存了对象,或者您可以使用obtainPermanentIDsForObjects:error:

6

下面是使用4中添加的setURL和getURL方法来执行此操作的最简洁最短的方法。0避免NSKeyedUnarchiver和额外的NSKeyedArchiver电话:

二传手:

+ (void)storeSomeObjectId:(NSManagedObjectID *)objectId 
{ 
    [[NSUserDefaults standardUserDefaults] setURL:[objectId URIRepresentation] 
              forKey:@"someObjectIdKey"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

消气:

+ (SomeManagedObject *)getObjectByStoredId 
{ 
    NSURL *uri = [[NSUserDefaults standardUserDefaults] URLForKey:@"someObjectIdKey"]; 
    NSManagedObjectID *objectId = [self.persistentStoreCoordinator managedObjectIDForURIRepresentation:uri]; 
    SomeManagedObject *object = [self.managedObjectContext objectWithID:objectId]; 
}