Additional notes on "Phantom Architecture" 3: Why "Circular references" are not generated

Source: Internet
Author: User

To take the above, the benefits of using structs instead of class are outlined, and using class will make our programs "accidental sharing" and "circular referencing" dangerous, and the reliance on class in traditional object-oriented development comes mainly from our reliance on "inheritance". Swift2.0 introduced protocol extensions, the previous "class-Inherit" functionality can be implemented using the "struct (enum)-Protocol-Protocol extension", and is more efficient and flexible. Back to the topic, first look at the two subjects in The Phantom Architecture: the Protocol for View and model:

//视图使用的协议protocol ViewType{    func getData<M:ModelType>(model:M)}//数据使用的协议protocol ModelType{}//定义默认方法giveDataextension ModelType{    func giveData<V:ViewType>(view:V){        view.getData(self)    }}

After you have generated an instance of model and view in the controller, you need to bind both of them:

dataList[indexPath.row].giveData(cell)

If you try to modify the order using:

cell.getData(dataList[indexPath.row])

In cases where DataList is a [Modeltype] type, the compilation cannot pass, but for a homogeneous array of [Festival] or [Event], it is possible to invoke the GetData method at the time of bundling, because the GetData parameter is generic, The elements in the array are modeltype types, not conforming to generic usage specifications, so the compiler will error, but why is the same generic method, which in turn calls Givedata? Givedata actually have a two-layer type check of the "gate", the first layer is givedata requires that the parameter is a generic type that complies with ViewType, and each cell instance in the demo is a specific type, so the cell can be used as a givedata parameter, And once the Givedata parameters passed the test, then in the Givedata default implementation of the method body, called the parameters of the GetData method, this method also requires passing in a specific type of compliance protocol, here passed the Self property, this property returns the instance itself, So it can pass the compiler's detection smoothly.
There is no longer a generic benefit, generics guarantee the transfer of raw data, rather than the process of one-step addressing as the protocol type, ensuring efficiency. So the data binding in the Phantom schema is removed from the controller code, but it is also efficient to directly perform data binding in the controller, in order to prove this, we add a Sizeofvalue method to the GetData method of the Tableviewcell subclass, Check the length of the parameter model:

Func getdata<m:modeltype> (model:m) {print (Sizeofvalue (model))//cannot be written as guard let Datemodel = model as? Dateviewmodel else{} made me a little surprised .Guard LetDatemodel = Model as? HasdateElse{return}//handling the same propertiesDatelabel.text = Datemodel.date//Processing data source heterogeneous        if  Let Event= Datemodel as? event{Mixlabel.text =Event. EventTitle backgroundcolor = Uicolor.redcolor ()}Else if  LetFestival = Datemodel as? festival{mixlabel.text = Festival.festivalname}}

Run, Print results:

Because we define festival and event with two string-type properties, each string is 24 bytes in size, so festival and event are 48 bytes, now we change the event to a class:

Class is a reference type, so its length on the stack is 8 bytes (the length of a pointer), you can see in the "Phantom Architecture" system, the model and view bindings do not produce the middle tier, the two are directly bound, then the problem, this mutual binding will not produce a "circular reference"?
First, if the model is a struct, there is no circular reference, and each value type has only one owner (because copy), and after the owner of the value type finishes executing, the value type is destroyed with the owner. Although a struct can define INIT, you will find that when you want to define a deinit method in a struct, the compiler prompts you that deinit can only be defined in the class:

So you don't have to care about the life cycle of the value type, so you've been changed to class event? In order to create a scenario that could cause a circular reference, we add a controller to the event reminder controller and a new controller and event reminder controller to connect with the navigation controller, which is now returned by the navigation bar when the event holiday reminder controller is collected by the system. All model and view instances should also be recycled, at which point a "circular reference" can be checked to define a deinit in the event:

class event:dateviewmodel{var      date  =   var  eventtitle =   Init (date : string , Eventtitle:string ) {self   date  =         date  self   EventTitle =  EventTitle} deinit{print ( "Deinit" )}}  

Now run the program, click the button to go to the Event Holiday Reminder List page, and then click Back to see the console print:

Thank goodness ^ ^. Now, to explain that the instance method in Swift is not actually saved in the instance, the instance method and the global method are different in that there is a namespace, as in the format of a class method, for example:

struct Test{    var""    var""    var""}

Use sizeof to see the size of the struct, display it as 72, and then add a method to it:

struct Test{    var""    var""    var""    func ab(str:String){        print(str)    }}

Look again at the size of test, which is still 72. The format we use when calling this method is:

a.ab("111")

But in fact we can also use this:

Test.ab(a)("111")

Here is the use of the curry, for instance method, first pass in an instance a, return a method that accepts a string type parameter, and then pass in our defined parameter type. So it is safe to use methods to bind data and views, because they are equally related and there is no dependency. This also explains why the capture list is explained in the official documentation, the ordinary closures and methods do not produce circular references, and only the closure is used as a parameter to generate circular references, as seen above, because the instance will only hold its own parameters and will not hold the method.

Additional notes on "Phantom Architecture" 3: Why "Circular references" are not generated

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.