- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我为一个表的inserting/updating/deleting/searching
相关的所有操作创建了一个NSOperationQueue
。我使用 MagicalRecord
进行核心数据操作。但是我在同步方面遇到了一些问题。一个简化的例子如下。
例如。一个名为 person
的表和一个名为 like
的 person 中的列。当用户点击一个按钮时,like
将增加 1。我喜欢做
[SameBackgroundQueue addOperationWithBlock:^{
User *user = [User MR_findFirstWithPredicate:some_predicate];
user.like += 1;
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
[SameBackgroundQueue addOperationWithBlock:^{
[self syncWithServer];//This can take time
}];
}];
但是,如果用户点击很快,like 就不会正确,因为MR_findFirstWithPredicate
会得到脏记录。问题源于 NSOperationQueue
可以使用不同的线程,而 MR_findFirstWithPredicate
使用当前线程的上下文。因此,它可能会尝试从不同的 NSManagedObjectContext
获取用户,因此它会获取脏数据。
当然如果我们使用mainQueue
,我们不会有任何问题。但是,如何使用后台线程并确保没有脏记录问题。如果我在一个特定线程而不是用户 NSOperationQueue 上运行,似乎可以解决整个问题。我应该改用 GCD 吗?
在我之前的项目中,我正在使用
[self createManagedObjectContextWithParent:self.mainQueueManagedObjectContext andConcurrencyType:NSPrivateQueueConcurrencyType];
和
[managedObjectContext save:&error];
if (managedObjectContext.parentContext) {
[managedObjectContext.parentContext performBlock:^{
NSError *parentError = nil;
[managedObjectContext.parentContext save:&parentError];
}];
}
我知道有 WWDC 视频在谈论 NSManagedObjectContext 和并发上下文等。但是如果我使用它,我就不能使用 MagicRecord。
任何建议将不胜感激。
实际上我找到了一种更有效的方法。如果我做错了,请纠正我。
我实际上创建了一个通用的 singleton 上下文 [NSManagedObjectContext MR_context]
以供 User OperationQueue 共享。所以即使所有线程访问同一个上下文,它们也不会得到脏数据。
仍然会有小故障,例如,如果两个线程正在更改同一上下文的同一对象怎么办。这通常是非常罕见的情况,但我会看看情况如何。我可能会将最大并发线程设置为一个,只是为了避免这种情况。我不确定它是否会降低性能。明天更新进度。
最佳答案
我建议将您的操作 block 更改为更像这样的内容:
[TheSameQueue addOperationWithBlock:^{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_context];
User *user = [User MR_findFirstWithPredicate:some_predicate inContext:localContext];
user.like += 1;
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
[self syncWithServer];//This can take time
}];
}];
您在默认上下文中执行所有后台操作,您可以将其视为主线程上下文。一般来说,这将在 99% 的时间内工作,但会导致随机死锁和崩溃。此外,MR_contextForCurrentThread 已被弃用,因为它还会导致队列出现问题,即为线程使用错误的上下文。
关于ios - NSOperationQueue、CoreData 和 MagicalRecord 同步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21691172/
我如何在 MagicalRecord 中为此找到替换方法(已弃用)?我看过谷歌、SO 和文档;似乎没有什么可以替代,当然,文档中没有任何内容告诉您是什么取代了已弃用的方法。 :-{ [[NSManag
我的服务器以“yyyy-MM-dd'T'HH:mm:ss'Z'”格式提供UTC日期,例如MST 的 11 月 15 日午夜是“2013-11-15T07:00:00Z”。这种格式是 MagicalRe
我像这样设置我的 MagicalRecord 堆栈: MagicalRecord.setupAutoMigratingCoreDataStack() let moc = NSManagedObject
@编辑@PangHoMing - 我会再次一步一步地做。首先设置 - 按照您的建议 MagicalRecord.setLoggingLevel(.verbose) MagicalRec
大家好, 我正在使用 MagicalRecord 并尝试删除两个实体之间建立的关系 联系>组 一个联系人可以与多个组相关,一个组也可以与多个联系人相关。 比如Ben在第1组,Alex也在第1组,我想把
我正在从我无法控制的网络服务中导入 JSON 响应。此响应包含我映射到 Show 实体的元素,该实体在同一 JSON 中具有多个相关的 Artwork 对象。 我通过 userinfo 键建立了关系,
似乎我什么都试过了,但似乎只在主线程中有效。例如: [SomeClass MR_createEntity]; [[NSManagedObjectContext MR_defaultContext] M
我使用 MagicalRecord 作为处理 Core Data 的一个很好的库。我的问题是如何在我的应用程序进入后台之前保存数据。因为我尝试通过 block 写入数据,当然它不会工作,因为应用程序将
我是 MagicalRecord 的新手。我在通过不同方法更新相同实体时遇到问题。这是我的例子:我有一些从网络服务获得的广告。完成后,如果有任何事件属性设置为 0,我需要更新数据库中的广告。我需要立即
我想知道为什么我的核心数据停止保存更改。事实上,上面的代码几小时前就可以工作了。当我尝试打印出错误时,它打印出 (null)。下面的代码是 NSManagedObjectSubclass 的自定义方法
我正在开发一款游戏,我正在使用 MagicalRecord 来存储高分。该游戏有 4 种模式和 2 种“类型”,因此有 8 种组合可供选择,我想为每一种组合打高分。我正在使用这个逻辑: NSArray
我尝试获取用户保存在应用程序中的所有元素(这可能很容易),从每条记录中获取一个属性并将这些属性列在一个字符串中(这就是问题所在)。我该怎么做?我写了一些东西,但我认为这不是正确的方法。请帮助我! -
我有这个代码: HLMReferenceData *referenceDataObj = [HLMReferenceData createEntity]; [MagicalRecord saveWit
我正在使用返回结果的网络服务,如下例所示: { "name":"Frank", "meals":[ "cheeseburger", "lasagne" ] }
我正在尝试将数据导入 Core Data 并使用 MagicalRecord 将其保存在后台线程中。 我基本上是在尝试这样做: __block User *user = nil; [MagicalRe
对于每次应用程序更新,我都想彻底删除我的整个 Core Data 数据库,然后重新设置它。我没有成功这样做。我尝试了各种方法,这似乎是我最接近的方法。我找到了几个 SO 帖子,但没有一个解决方案适合我
在 iOS5.0 中,使用 arc,我使用 Magical record 在核心数据中创建对象。我有一个产品对象,它与 Promotion 对象具有称为“currentPromotions”的一对多关
我有以下格式的日期: 2013-05-04T05:07:09+00:00 我正在使用 MagicalRecord 自动映射 NSDate。据我所知,上述日期格式应符合 MagicalRecord 的默
我有以下代码: dispatch_async(dispatch_get_main_queue(), ^{ NSManagedObjectContext *localContext = [NSM
我正在尝试 MagicalRecord 的一些非常基本的实现,以掌握它并遇到以下问题。 当我保存一个条目然后获取该类型的条目时,它会出现我刚刚保存的条目。但是,当我保存条目、关闭应用程序、重新启动它然
我是一名优秀的程序员,十分优秀!