想象一下CoreData实体(例如命名searchEngine
).
NSManagedObjectContext
管理该实体的一些"实例".
最终用户将能够选择他"standard searchEngine"
的NSPopupButton
.
该selected object
NSPopupButton应绑定到的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.
如果需要存储对特定托管对象的引用,请使用其托管对象ID的URI表示:
NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];
然后,您可以将URL保存为用户默认值.
要检索托管对象,请使用:
NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL]; NSManagedObject *myManagedObject = [myContext objectWithID:moID];
唯一需要注意的是,您必须确保原始托管对象ID是永久性的 - 如果您已经保存了对象,则这不是问题,您也可以使用obtainPermanentIDsForObjects:error:
.
这是目前使用4.0中添加的setURL和getURL方法执行此操作的最简洁和最短的方法,以避免额外调用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]; }
您不希望尝试归档核心数据实体并将其存储.相反,您将存储密钥或其他一些已知属性,并在应用程序启动时使用它来获取实体.
一些示例代码(稍微修改自" 核心数据编程指南"中发布的示例):
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... }
这样,您可以将名称保存在用户默认值中,并在必要时获取实体.