Class 或结构类似于关系数据库的模型?
Class or Struct for a model similar to a relational database?
有问题的应用程序构建如下:
- 用户选择了一份工作
- 作业可以有很多组成部分
- 每个组件可以有很多行项目。
我不清楚这应该如何构建 - 这应该是 class 还是结构?看到一次只处理一个作业,我相当有信心作业应该是 class。但是,当某个对象类型有多个时,我不太清楚如何形成它们,比如组件和 lineitem 对象。
该应用程序由 ViewController 和 TableViewController 组成。所有数据都从 JSON 中的服务器获取,并根据需要填充到适当的视图中。以下是当前设置的对象类型:
一个工作对象:
// Job Object
//
public struct Job {
static var globalId : String?
static var name : String?
static var status : String?
static var client = Client()
static var components = Array<Component>()
// etc..
}
像这样的组件:
// JobComponent Object
//
public struct Component {
var name:String? = ""
var fmRecordId : String?
var startTS:NSDate?
var endTS:NSDate?
var notes:String? = ""
var items = Array<Lineitem>()
// etc...
}
最后,一个项目:
// Lineitem Object
//
public struct Lineitem {
var fmRecordId = String()
var itemName = String()
var itemNumber = String()
// etc...
}
所有这些对象都构建在名为 "PL" 的 public class
中。
当用户选择 lineitem 并编辑它的值时,这些值在编辑它们的 VC 之外不可用,因为 VC 没有引用传递的 lineitem,它只是在复制它。组件也是如此。
我发现的解决方法是使用 Job 结构 PL.Job.self
并始终像这样修改组件和行项目,其中 i
= 数组中的所需索引:
PL.Job.components[i]
访问组件
PL.Job.components[i].items[i]
以访问该组件中的特定项目。
然而,这并不能很好地扩展。
期望的行为是能够传递对对象特定实例的引用,而不是传递 PL.Job
对象中那些对象的索引路径。
我很清楚目前的结构有问题,但有人能给我指出正确的方向吗?
几点:
您只能通过引用传递 class 个实例。如果您希望能够传递对特定 LineItem
或 Component
或 Job
的引用,并且您希望能够对该对象进行在任何地方都有效的更改,那么您需要将它们定义为 classes 而不是结构。结构类型的实例总是按值传递而不是引用。当一个值类型被传递时,它被复制,这意味着你创建了一个全新的对象副本,并且改变副本对原始副本没有影响。
你的 Job
结构只有静态属性——也就是说,在整个过程中只会有一个 globalId
、name
、status
等你的整个应用程序。如果你想要 Job
的多个实例,那么这些不应该是静态属性。您说一次只会处理一个 Job
,所以这可能是故意的。无论哪种方式,创建具有这些属性的 Job
class 的实例通常仍然更可取。如果您决定在内存中保存对多个作业的引用,或者允许用户在不同的作业之间 select,或者在作业之间切换等,它肯定会给您以后更大的灵活性。例如,您可能希望允许用户切换到他们之前正在处理的 Job
,而不必破坏他们现在正在处理的 Job
。
但我认为要点是,如果您希望能够通过引用传递对象,则需要将对象定义为 classes。如果修改通过引用传递的对象,则对同一对象的所有其他引用将显示相同的更改(因为毕竟它们只是对同一对象的引用)。这不适用于值类型,例如结构。
有问题的应用程序构建如下:
- 用户选择了一份工作
- 作业可以有很多组成部分
- 每个组件可以有很多行项目。
我不清楚这应该如何构建 - 这应该是 class 还是结构?看到一次只处理一个作业,我相当有信心作业应该是 class。但是,当某个对象类型有多个时,我不太清楚如何形成它们,比如组件和 lineitem 对象。
该应用程序由 ViewController 和 TableViewController 组成。所有数据都从 JSON 中的服务器获取,并根据需要填充到适当的视图中。以下是当前设置的对象类型:
一个工作对象:
// Job Object
//
public struct Job {
static var globalId : String?
static var name : String?
static var status : String?
static var client = Client()
static var components = Array<Component>()
// etc..
}
像这样的组件:
// JobComponent Object
//
public struct Component {
var name:String? = ""
var fmRecordId : String?
var startTS:NSDate?
var endTS:NSDate?
var notes:String? = ""
var items = Array<Lineitem>()
// etc...
}
最后,一个项目:
// Lineitem Object
//
public struct Lineitem {
var fmRecordId = String()
var itemName = String()
var itemNumber = String()
// etc...
}
所有这些对象都构建在名为 "PL" 的 public class
中。
当用户选择 lineitem 并编辑它的值时,这些值在编辑它们的 VC 之外不可用,因为 VC 没有引用传递的 lineitem,它只是在复制它。组件也是如此。
我发现的解决方法是使用 Job 结构 PL.Job.self
并始终像这样修改组件和行项目,其中 i
= 数组中的所需索引:
PL.Job.components[i]
访问组件PL.Job.components[i].items[i]
以访问该组件中的特定项目。
然而,这并不能很好地扩展。
期望的行为是能够传递对对象特定实例的引用,而不是传递 PL.Job
对象中那些对象的索引路径。
我很清楚目前的结构有问题,但有人能给我指出正确的方向吗?
几点:
您只能通过引用传递 class 个实例。如果您希望能够传递对特定
LineItem
或Component
或Job
的引用,并且您希望能够对该对象进行在任何地方都有效的更改,那么您需要将它们定义为 classes 而不是结构。结构类型的实例总是按值传递而不是引用。当一个值类型被传递时,它被复制,这意味着你创建了一个全新的对象副本,并且改变副本对原始副本没有影响。你的
Job
结构只有静态属性——也就是说,在整个过程中只会有一个globalId
、name
、status
等你的整个应用程序。如果你想要Job
的多个实例,那么这些不应该是静态属性。您说一次只会处理一个Job
,所以这可能是故意的。无论哪种方式,创建具有这些属性的Job
class 的实例通常仍然更可取。如果您决定在内存中保存对多个作业的引用,或者允许用户在不同的作业之间 select,或者在作业之间切换等,它肯定会给您以后更大的灵活性。例如,您可能希望允许用户切换到他们之前正在处理的Job
,而不必破坏他们现在正在处理的Job
。
但我认为要点是,如果您希望能够通过引用传递对象,则需要将对象定义为 classes。如果修改通过引用传递的对象,则对同一对象的所有其他引用将显示相同的更改(因为毕竟它们只是对同一对象的引用)。这不适用于值类型,例如结构。