想象一下CoreData实体(例如名为searchEngine
)
NSManagedObjectContext
管理此实体的某些“实例”
最终用户可以选择"standard searchEngine"
NSPopupButton
。{。}
NSPopupButton的selected object
应绑定到NSUserDefaults
问题:
1)
@try {save}
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
答案 0 :(得分:35)
如果需要存储对特定托管对象的引用,请使用其托管对象ID的URI表示:
NSURL *moIDURL = [[myManagedObject objectID] URIRepresentation];
然后,您可以将URL保存为用户默认值。
要检索托管对象,请使用:
NSManagedObjectID *moID = [myPersistentStoreCoordinator managedObjectIDForURIRepresentation:moIDURL];
NSManagedObject *myManagedObject = [myContext objectWithID:moID];
唯一需要注意的是,您必须确保原始托管对象ID是永久性的 - 如果您已经保存了对象,则这不是问题,或者您可以使用obtainPermanentIDsForObjects:error:
。
答案 1 :(得分:7)
目前使用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];
}
答案 2 :(得分: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...
}
这样您就可以在用户默认值中保存名称,并在必要时获取实体。
答案 3 :(得分:0)
我的模型将记录的UUID保存到UserDefaults中,以便在下一次应用程序启动时启动最后打开的记录。
public class Patient: NSManagedObject {
override public func awakeFromInsert() {
super.awakeFromInsert()
uuid = UUID()
}
extension Patient {
@NSManaged public var uuid: UUID
@NSManaged ...
}
优良作法是用唯一的ID(UUID)标识每条记录。您只需调用uuid.uuidString
即可将UUID保存为字符串。