草庐IT

ios - NSFetchedResultsController 正在删除行而不是在更新核心数据后更新它们

coder 2023-09-17 原文

在我的 TableView 中使用 NSFetchedResultsController 时,数据在创建新的 NSManagedObject 后立即正确显示,但所有行/部分在更新后都被删除。下面,当调用 update() 方法并保存联系人时,我的打印语句输出行和部分正在从 TableView 中删除。调用 create() 方法时,将插入行/节(如预期的那样)。

运行后两组不同的输出:

从 API 请求中检索到信息后,如果该项目已经存在(由唯一 ID 指定),我将更新相应的核心数据模型,如下所示:

func update(oldContact: NSManagedObject) -> Bool {

    //updates contact
    let contact = populateObject(oldContact)

    // Delete existing phones
    if let phoneDataSet = contact.valueForKeyPath("phones") {
        let phonesArray = phoneDataSet.allObjects as! [NSManagedObject]
        for object in phonesArray {
            context.deleteObject(object)
        }
    }
    // Add phones from response
    for phone in phones {
        phone.createForContact(contact)
    }

    // Save contact
    do {
        try contact.managedObjectContext?.save()
        print("saving contact")
        return true
    } catch {
        let nserror = error as NSError
        print("error upong saving")
        NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
        abort()
    }

    return false
}

  func populateObject(object: NSManagedObject) -> NSManagedObject {

    object.setValue(self.name, forKey: "name")
    object.setValue(self.id, forKey: "id")
    object.setValue(self.firstLetter, forKey: "firstLetter")

    return object
  }

如果该项在核心数据中不存在,则创建如下:

func create() -> Bool {

    // Quit if contact already exists.
    let data = CoreData().searchObject("Contact", predicate: "id", value: String(self.id))
    guard data == nil else { fatalError("Attempted to insert duplicate contact") }

    //creates a new contact NSManagedObject
    var newContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: context)
    //sets the contact values
    newContact = populateObject(newContact)

    //creates Phone NSManagedObject, then makes a relationship with contact
    for phone in self.phones {
        phone.createForContact(newContact)
    }

    do {
        //saves the contact object; also saves the relationship with the phone number
        try newContact.managedObjectContext?.save()
        print("Creating contact")
        return true;
    } catch {
        let nserror = error as NSError
        NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
        abort()
    }

    return false
}

我的 FetchedResultsController 委托(delegate)方法如下所示:

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch (type) {
    case .Update:
        if let indexPath = indexPath {
            if let cell = tableView.cellForRowAtIndexPath(indexPath) as? PeopleAndPlaceCell {
                configureCell(cell, atIndexPath: indexPath)
                tableView.reloadRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
                print("UPDATING ROW")
            }
        }
        break;
    case .Insert:
        if let indexPath = newIndexPath {
            tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            print("INSERTING ROW")
        }
        break;
    case .Delete:
        if let indexPath = indexPath {
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            print("DELETING ROW")
        }
        break;
    case .Move:
        if let indexPath = indexPath {
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        }

        if let newIndexPath = newIndexPath {
            tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
        }
        break;
    }
}

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
    switch type {
    case .Update:
        print("UPDATE SECTION")
        break
    case .Insert:
        self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
        print("INSERTING SECTION")
    case .Delete:
        self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
        print("DELETING SECTION")
    case .Move:
        break
    }
}

更新:

Contact 到 Phone 是一对多的关系,而从 Phone 到 Contact 是一对一的关系。 Phone 实体中联系关系的删除规则是级联。对于Contact实体中的phone关系也是级联的。

最佳答案

问题是 Phone 实体的 contact 关系的“级联”删除规则的结果。在您的 update() 方法中,您删除了给定 Contact 的所有“旧”Phone 对象。级联删除规则导致 Contact 也被删除。将此删除规则更改为“无效”。 (你可以在Contact实体中保留反向关系,phones,作为“Cascade”:当你删除一个Contact时,它会删除所有关联的 Phone)。

关于ios - NSFetchedResultsController 正在删除行而不是在更新核心数据后更新它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35975504/

有关ios - NSFetchedResultsController 正在删除行而不是在更新核心数据后更新它们的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  5. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  8. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  9. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  10. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

随机推荐