2

I have a question about struct

In WWDC2016, session recommend to use sturct (value type)

but if structs have 3 more inline variable words, struct must manage reference count as store large value to heap

then my question is
when struct have 3 another struct and each struct have 2 or 3 another struct or value type

I want to know how it works whether using reference Count or not in this situation

below is example of structs

struct ViewModel {
     var titleModel: TitleModel
     var contentModel: ContentModel
     var layoutModel: LayoutModel
}

struct TitleModel {
     var text: String
     var width: Float
     var height: Float
}

struct ContentModel {
     var content: String
     var width: Float
     var height: Float
}

struct LayoutModel {
     var constant: Float
     var multiply: Float
}
Cruz
  • 2,602
  • 19
  • 29
  • 2
    I believe when you talk about reference counting with structs, you're referring to the part of [this WWDC talk](https://developer.apple.com/videos/play/wwdc2016/416/) where they talk about the existential container, which can incur heap allocation if the value buffer exceeds 3 words. This is only relevant when using structs with protocol types, and (generally) unoptimised generic code – but (as the answers below say) is not applicable to the code you've shown. – Hamish Jul 19 '16 at 14:02

2 Answers2

5

Structures and enumerations have value-semantics. There is no notion of a reference count, because they are passed by copying. Their members may be pointers to reference-types, but the pointer itself is copied. As long as you don't have a reference-type in a structure, you don't need to worry about reference counting.

Sure, one may argue that Swift internally uses copy-on-write optimizations using reference-types disguised as structures (eg. Array, Dictionary etc.), but they implement value-semantics.

Vatsal Manot
  • 17,695
  • 9
  • 44
  • 80
3

See these number of sizes of your structs.

print(sizeof(ViewModel))     //->72 == sizeof(TitleModel) + sizeof(ContentModel) + sizeof(LayoutModel)
print(sizeof(TitleModel))    //->32 == sizeof(String) + sizeof(Float) + sizeof(Float)
print(sizeof(ContentModel))  //->32 == sizeof(String) + sizeof(Float) + sizeof(Float)
print(sizeof(String))        //->24 (a mystery...)
print(sizeof(LayoutModel))   //->8 == sizeof(Float) + sizeof(Float)

(sizeof(String) seems to be a "mystery", but that also is another problem.)

Swift does not give us any guarantees about member allocation in a struct, but, as for now, Swift allocates all members in a way "flat and natural".

 ViewModel:
 offset content                 size
  0     TitleModel.text          24
 24     TitleModel.width          4
 28     TitleModel.heigth         4
 32     ContentModel.content     24
 56     ContentModel.width        4
 60     ContentModel.height       4
 64     LayoutModel.constant      4
 68     LayoutModel.multiply      4
 --
 72     Total(=sizeof(ViewModel))

Your ViewModel does not contain references to its members. It just holds its members flatly inside. No references, so, no reference counts.

You may have a question about how structs are managed when they actually contain some references. But that is another issue than your when struct have 3 another struct and each struct have 2 or 3 another struct or value type.

OOPer
  • 47,149
  • 6
  • 107
  • 142