gpt4 book ai didi

core-data - 永久 NSManagedObjectID 不是那么永久吗?

转载 作者:行者123 更新时间:2023-12-04 02:59:19 25 4
gpt4 key购买 nike

我在处理 CoreData 中的对象 ID 时遇到问题。为方便起见,我使用 MagicalRecord 并具有 3 个上下文:私有(private)队列工作上下文、UI 的主队列上下文和工作上下文的父级,以及作为主上下文父级的私有(private)队列保存上下文。

我的目标是在工作上下文中创建一个对象,保存到持久存储,将它的 objectID URL 保存到 NSUserDefaults,然后稍后能够使用 objectID 拉出 MO。但是,我发现保存对象的永久 ID 后正在发生变化。

在下面的控制台输出中,您可以看到,在我请求永久 ID 后,我得到的值是“F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p1”,但后来当我列出 CD 中的所有对象时,那里唯一的对象ID 为“F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2”。 p1 vs p2,发生了什么?

代码:

  NSManagedObjectContext *c = [NSManagedObjectContext MR_contextThatPushesChangesToDefaultContext];
[c performBlockAndWait:^{

NSArray *all = [CDBaseAccount MR_findAllInContext:c];
NSLog(@"count: %d", all.count);
NSLog(@"all accounts = %@", all);

CDBaseAccount *a = [CDBaseAccount MR_createInContext:c];
a.accountName = @"foo";

[c MR_saveNestedContexts];

NSLog(@"temp a.objectID = %@", a.objectID);

NSError *error;
if (![c obtainPermanentIDsForObjects:@[a] error:&error]) {
NSLog(@"perm id error: %@", error);
return;
}

NSLog(@"perm a.objectID = %@", a.objectID);

NSURL *u = a.objectID.URIRepresentation;

dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *d = [NSManagedObjectContext MR_defaultContext];

NSArray *all = [CDBaseAccount MR_findAllInContext:d];
NSLog(@"count: %d", all.count);
NSLog(@"all accounts = %@", all);

NSManagedObjectID *i = [d.persistentStoreCoordinator managedObjectIDForURIRepresentation:u];
NSError *objWithIdError = nil;
NSManagedObject *o = [d existingObjectWithID:i error:&objWithIdError];
if (objWithIdError != nil) {
NSLog(@"existing object error: %@", objWithIdError);
return;
}

NSLog(@"o = %@", o);
NSLog(@"o.objectID = %@", o.objectID);

});
}];

控制台输出:
  > +[NSManagedObjectContext(MagicalRecord) MR_contextWithStoreCoordinator:](0xa7c9b0) -> Created <NSManagedObjectContext: 0x83522a0>:  Context *** MAIN THREAD ***
> count: 0
> all accounts = (
> )
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x8353de0) -> Saving <NSManagedObjectContext: 0x8353de0>: Context *** MAIN THREAD ***
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x8195450) -> Saving <NSManagedObjectContext: 0x8195450>: *** DEFAULT *** Context *** MAIN THREAD ***
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x83522a0) -> Saving <NSManagedObjectContext: 0x83522a0>: *** BACKGROUND SAVE *** Context *** MAIN THREAD ***
> temp a.objectID = 0x8187ee0 <x-coredata:///CDBaseAccount/tF392AC6A-3539-4F39-AC53-35F9E5B3C9322>
> perm a.objectID = 0x8355800 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2>
> count: 1
> all accounts = (
"<CDBaseAccount: 0x844ca60> (entity: CDBaseAccount; id: 0x844a4c0 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p1> ; data: <fault>)"
)
> existing object error: Error Domain=NSCocoaErrorDomain Code=133000 "The operation couldn’t be completed. (Cocoa error 133000.)" UserInfo=0x864d8c0 {NSAffectedObjectsErrorKey=(
"<CDBaseAccount: 0x864b8c0> (entity: CDBaseAccount; id: 0x86405c0 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2> ; data: <fault>)"
)}

最佳答案

简短的回答是,不要那样做:)
-objectID在您的应用程序启动之间不可靠。在以下条件下保证其唯一性和可靠性:

  • 在应用程序的单个生命周期内
  • 以其原始对象形式(不是 URL 或 NSString 形式)

  • 治疗 -objectID作为要存储在持久存储之外的永久唯一标识符,您会经常失败。 Core Data 更改了 -objectID 的底层细节在对象的生命周期中多次。

    如果您需要一个外部可靠的唯一性,那么您需要自己创建一个。我一般建议添加 [[NSProcessInfo processInfo] globallyUniqueString]任何需要外部引用唯一的实体。 -awakeFromInsert是这样做的好地方。

    关于core-data - 永久 NSManagedObjectID 不是那么永久吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12218396/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com