Ios Swift:到结构,还是不到结构
我终于从Objective-C转到Swift了。我正在为我的客户创建一个视图布局系统,使他们的应用程序在布局上更加灵活,而不使用自动布局,因为他们希望远程设计屏幕,而自动布局对他们来说太复杂了。我尝试使用Ios Swift:到结构,还是不到结构,ios,swift,class,struct,Ios,Swift,Class,Struct,我终于从Objective-C转到Swift了。我正在为我的客户创建一个视图布局系统,使他们的应用程序在布局上更加灵活,而不使用自动布局,因为他们希望远程设计屏幕,而自动布局对他们来说太复杂了。我尝试使用structs和protocols来实现这一点,但我发现它相当笨拙,因此我怀疑我的想法不正确 对于类,结构如下所示: class ViewModel { var frame: CGRect = .zero } class ViewGroupModel: ViewModel {
structs
和protocols
来实现这一点,但我发现它相当笨拙,因此我怀疑我的想法不正确
对于类,结构如下所示:
class ViewModel {
var frame: CGRect = .zero
}
class ViewGroupModel: ViewModel {
var weight: Int = 1
var children:[ViewModel] = [ViewModel]()
}
class HorizontalViewGroupModel: ViewGroupModel {
}
class VerticalViewGroupModel: ViewGroupModel {
}
我试图通过定义一个ViewModel
协议和一个ViewGroupModel
协议来使用协议,但我发现它创建了大量重复(属性)。有更好的方法吗?在这种情况下使用类是否被认为是一种好的做法
编辑:如果不使用类会更好,我正在寻找一个答案,它可以为我提供一个具体的解决方案,包括
结构
和协议
通常,只有在需要类的特殊功能时才使用类,这些功能是:
- 一个类可以有一个超类和/或一个子类;结构不能
- 类是值类型,而结构是值类型
- Objective-C可以内省类(特别是如果它派生自NSObject),但它甚至看不到Swift中声明的结构
关于详细的讨论,你可以通过我的帖子。如果问题仅仅是如何实现协议的属性,我不一定会让它影响我在
struct
vsclass
之间的选择。如果您的struct
类型必须实现多种属性,则有两个基本选项:
结构中实现符合该协议的那些属性即可。我们一直都这样做。例如,在定义符合MKAnnotation
的自定义类型时,我们只需实现三个必需的属性
当然,如果我们讨论的是一组更大的属性,这会变得很乏味,但是编译器会在整个过程中帮助我们,确保我们不会遗漏任何东西。因此,挑战相当小
struct
包装所有这些属性,然后在扩展中实现协议的默认计算属性:
enum SubviewArrangement {
case none
case horizontal
case vertical
case flow
}
struct ViewComponent {
var frame = CGRect.zero
var weight = 1
var subviews = [ViewModel]()
var subviewArrangement = SubviewArrangement.none
}
protocol HasViewComponent {
var viewComponent: ViewComponent { get set }
}
protocol ViewModel: HasViewComponent { }
extension ViewModel {
var frame: CGRect {
get { return viewComponent.frame }
set { viewComponent.frame = newValue }
}
var weight: Int {
get { return viewComponent.weight }
set { viewComponent.weight = newValue }
}
var subviews: [ViewModel] {
get { return viewComponent.subviews }
set { viewComponent.subviews = newValue }
}
var subviewArrangement: SubviewArrangement {
get { return viewComponent.subviewArrangement }
set { viewComponent.subviewArrangement = newValue }
}
}
其中,您可以创建符合ViewModel
的实例,如下所示:
struct LabelModel: ViewModel {
var viewComponent = ViewComponent()
}
var label = LabelModel()
label.weight = 2
print(label.weight)
我必须承认,这不是最优雅的方法。(我甚至不愿意展示它。)但它避免了在符合ViewModel
的类型中单独实现所有这些属性struct
)还是引用类型(class
)。我认为这是一个启发性的考虑苹果的价值讨论VS参考语义接近尾声(@ 4:15)的视频。它们涉及到那些您实际上可能仍然想要使用类的情况。例如,他们建议您在“复制或比较实例没有意义”时使用引用类型。他们建议在处理“窗口”实例时可以应用此规则。这一点在这里也适用
除此之外,在我看来,使用值类型来表示视图层次结构并没有多大好处,视图层次结构是引用类型对象的集合。这只会让事情变得更加混乱。我会坚持使用类
类型,因为它将准确地反映它所表示的视图层次
别误会我的意思:我们太习惯使用引用类型了,所以我认为挑战我们的先入为主的观念并仔细研究一个值类型是否能更好地解决这种情况总是好的。不过,在这种情况下,我不必担心它,只需坚持使用反映正在建模的对象层次结构的类
层次结构即可
尽管如此,您在问题中提出的类层次结构也感觉不太正确。您实际上可以实例化一个
ViewModel
,以后无法向其中添加子视图(而所有UIView
对象都有subview
属性),这让人感到奇怪。此外,您的水平和垂直组类型也感觉不正确。例如,它是否应该是具有某些“axis”属性的单一类型,如UIStackV