【问题标题】:Swift structure not updated after modifying in a block在块中修改后未更新 Swift 结构
【发布时间】:2015-06-17 09:50:39
【问题描述】:

我正在用 Swift 编写一个 iOS 应用程序,但遇到了一些关于结构和块的问题。当用户编辑他的教育信息并单击保存按钮时,我向服务器发送请求并更新成功处理程序中的本地数据。这里我在EditController类中写了一个editItem()函数,在UserModel类结构中写了一个editEducation()

class EditController: UITableViewController {

    //...

    func editItem<T>(item: T, completion: () -> Void) {
        switch selectedType {
            case .Education:
                let educationItem = item as! EducationModel
                // self.user is a object of type "UserModel"
                user!.editEducation(index: selectedRow, educationItem: educationItem) {
                    // breakpoint 2 here
                    completion()
                    self.tableView.reloadData()
                }
            default:
                return
        }
    }

    //...

}

struct UserModel {

    //...

    var education = [EducationModel]()
    //EducationModel is also a structure

    //...

    mutating func editEducation(#index: Int, educationItem: EducationModel, completion: () -> Void) {
       let manager = HTTPClient.sharedManager
       manager.POST("/user/education/update",
           parameters: [
               // params
           ],
           success: { (task, responseObject) in
               if responseObject["status"] as! Int == 0 {
                   self.education[index] = educationItem
                   // breakpoint 1 here
                   completion()
               } else {
                   println(responseObject)
               }
           },
           failure: { (task, error) in
               println(error)
           }
       )
    }

    //...

}

问题是,尽管self.education 在程序到达断点 1 时成功更新(如上所述),self.user.education 仍然包含断点 2 处的旧数据。如果我移动

self.education[index] = educationItem

在 POST 请求之外,数据在断点 2 处按预期更新。我尝试通过在断点 2 处添加调度来延迟,但它仍然不会更新。我还打印了相关变量的内存地址,但它没有提供任何有用的信息。我现在通过向editEducation 添加一个controller 参数来处理这个问题,在EditController 中传递self 并强制更新控制器的user 属性。我认为这不是一个适当的解决方案。那么有没有更好的方法来做到这一点?

更新 1

我尝试将 UserModel 转换为一个类,它解决了问题,但我不想这样做,因为:首先,如果我将它设为一个类,应用程序其他部分的某些行为可能会变得奇怪,其次我必须这样做将其他数十个模型转为类以确保一致性。

【问题讨论】:

    标签: ios swift cocoa cocoa-touch


    【解决方案1】:

    您在这里看到的是值类型(结构)和引用类型(类)之间的区别。您应该阅读 Apple 网站上关于差异的博文:https://developer.apple.com/swift/blog/?id=10

    基本上,一旦您将结构传递到块中,它就会被复制而不是被引用,因此您正在处理一个全新的副本。通过课程,您可以获得对原始副本的参考。

    【讨论】:

    • 我尝试在成功块外部和内部的 editEducation() 中打印 self 的内存,结果它们是相同的。这是否意味着进入块时不会复制该值?
    • 它们在写入时复制。所有引用类型将是同一个实例,即使在它们被修改之前被复制。我猜你在修改它之前检查了地址之前
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    相关资源
    最近更新 更多