gpt4 book ai didi

ios - 核心数据 : Set relationship from query result causes memory corruption (Swift 2)

转载 作者:行者123 更新时间:2023-11-28 08:57:20 27 4
gpt4 key购买 nike

我最近更新到 Xcode 7 并将一个工作项目从 Swift 1.2 转换为 Swift 2。这样做之后,我遇到了非常奇怪的核心数据行为,通常表现为内存损坏(例如 malloc 相关的错误指针等)。

最终,我发现在子核心数据项中设置“后向指针”关系并引用作为查询结果返回的核心数据项似乎会导致崩溃。 (也就是说,我不再设置这个返回指针关系,奇怪的行为也停止了。)

给定以下托管对象,其中 Subject 是父对象,ContentItem 是子对象:

class SubjectItem: NSManagedObject {
@NSManaged var configured: NSNumber
@NSManaged var friendlyName: String
@NSManaged var fullname: String
@NSManaged var isMe: NSNumber
@NSManaged var position: NSNumber
@NSManaged var profilePictureUrl: String
@NSManaged var selected: NSNumber
@NSManaged var source: String
@NSManaged var subjectid: String
@NSManaged var subjectname: String
@NSManaged var sourceId: String
@NSManaged var toContentItems: ContentItem
}

class ContentItem: NSManagedObject {
@NSManaged var createdTime: NSDate
@NSManaged var itemID: String
@NSManaged var owner: String
@NSManaged var source: String
@NSManaged var type: String
@NSManaged var position: NSNumber
@NSManaged var toCaption: CaptionItem
@NSManaged var toImages: ImageItems
@NSManaged var toSubject: SubjectItem
@NSManaged var toVideos: VideoItems
}

注意 ContentItem 对象中指向 Subject 的“后向指针”。

主题在内容项之前单独保存。保存内容项时,我有一个函数可以查找正在保存的内容项(子项)的相关主题(父项):

class func findSubject(subjectid: String) -> SubjectItem? {
let moc = getManagedObjectContext()
let request = NSFetchRequest(entityName: SubjectEntity)
let predicate = NSPredicate(format: "subjectid == %@", subjectid)
request.predicate = predicate

var subject: SubjectItem? = nil
do {
let subjects = try moc.executeFetchRequest(request)
if subjects.count > 0 {
subject = subjects[0] as? SubjectItem
}
} catch {
print("Error finding subject")
}
return subject
}

持久化内容项的代码设置了内容项上的查找函数返回的引用。该函数如下所示:

if let subject = SubjectItem.findSubject(owner) {
let contentItem = ContentItem.createContentItem(post: post, owner: owner)
contentItem.toSubject = subject

// ... more stuff ...
}

在插入新对象的 ContentItem 的扩展中有一个类函数:

extension ContentItem {
class func createContentItem(post post: Post, owner: String) -> ContentItem {
let moc = getManagedObjectContext()
let contentItem = NSEntityDescription.insertNewObjectForEntityForName(ContentEntity, inManagedObjectContext: moc) as! ContentItem

contentItem.itemID = post.id
contentItem.type = post.type!
contentItem.createdTime = post.createdTime!
contentItem.owner = owner
contentItem.source = MediaSource.Instagram.rawValue
contentItem.position = 0

return contentItem
}

移除内容项后向指针对获取主题的分配可以解决内存问题。

更新:我没有提到保存 ContentItem 对象时发生的奇怪行为。保存导致 NSFetchedResultsController 监控的查询触发(它应该)。就是在 NSFetchedResultsController 处理保存的 ContentItem 对象的时候,会出现内存错误。

我在这里做违法的事情吗?为什么这在 Swift 1.2 中有效?

最佳答案

对于多线程核心数据应用程序,我建议让实体创建便利方法将上下文作为参数。通过这种方式,您可以从任何地方调用他们,甚至可以在必要时当场保存。

class func createContentItem(post: Post, owner: String, 
context: NSManagedObjectContext) -> ContentItem {

context.performBlockAndWait() {
let contentItem = NSEntityDescription.insertNewObjectForEntityForName(
ContentEntity, inManagedObjectContext: context)
// ...
do { try context.save() } catch {}
}
}

为了额外的安全,将您的操作包装在一个单独的 block 中,如图所示。

关于ios - 核心数据 : Set relationship from query result causes memory corruption (Swift 2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32751784/

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