Brief description
name |
function |
Set |
Evaluates a property's assignment method, which is called when the property is set |
Get |
The reading method of the computed property, when the property is worth calling |
Willset (NewValue) |
Methods for monitoring properties, called when property values are about to change, with values that are about to change |
Didset (OldValue) |
Methods for monitoring properties, called after property values have changed, and values preceded by changes to parameters |
? And! |
The nullable identifier for the property. ? indicates a nullable,! Indicates forced unpacking |
Set and get
In OC, the property is implemented by the set and get methods, that is, when the call property is actually called the property's set and get method, through the Setget method to implement a global variable in the class read and write, There is no immediate way to write set and get methods, both of which are implicitly present. The following is the implementation prototype of the properties in OC
//normal way Declaration property @property (nonatomic , copy) NSString * STR; //------------------------------------ xx.h //internal principle {nsstring * STR;} -(void ) SetObject: (nsstring *) anstr;-(nsstring *) getstr;xx {nsstring * _object;} -(void ) SetObject: (nsstring *) anobject{_ Object = AnObject;} -(nsstring *) getobject{return _object;}
See, the OC attribute is actually an operation on a global variable inside a class. We can override the set and get methods to implement the monitoring of property changes, implicit modification of attributes, and so on.
The set and get methods in Swift are not required. The Assert property is a direct generation of a stored property, there is no implicit set and get method, and only computed properties can be used with the set and get methods. The computed property itself is not a value, is just a dummy property that can call set and get methods through a dot.计算属性并不能储存任何数据且必须实现get方法
class Object: NSObject { //声明一个计算属性 var age:Int{ get{ print("get"); } set(newValue){ print("\(newValue)") } }}//下面对这个属性进行使用10;print("\(man.age)")
Output Result:
set:10 //设置age的值 触发set方法并将值传递给set方法的参数newValueget //输出age的值触发了get方法0 //输出age的值为0
You can see that the first call set method to pass the value of the set, NewValue is passed in the value, after the completion of the output Man.age property, triggered the call of the Get method, the last output of the value of age, the output is 0, In other words, the value of the setting is not saved. To look at the OC attribute principle, is it a bit like this, if you create a private global variable in Swift to store the value of the set, and then return it when it is read is not the same as in OC?
privatevar0; var age:Int{ get{ print("get") return newAge } set(newValue){ newAge = newValue; print("set:\(newValue)") } }
Output Result:
set:10get10
Okay, so this restores the attribute format in OC, in which we can manipulate the value of the property 由于swift中默认属性没有set和get方法 所以我们无法重写父类属性的set和get方法
.
Willset and Didset
These two methods belong to the attribute observer. This is called after the attribute value is to be set and set. The method that is a basic attribute, you can override these two methods of the parent class property to implement the function of overriding the set method in the original OC. The difference is that when you initialize a property value, the two methods are not called. It is therefore a property observer.
//创建一个观察者属性 var "0"{ willSet(new){ print("will:\(new)"); } didSet(old){ print("did:\(old)"); } } //调用 var man = People() "sad"; print("\(man.name)"); //输出结果
Output Result::
//将要设置值得时候调用,传递将要设置的值did:0 //设置完毕,传递一个设置之前的值sad //最终的值
The test results show that在第一次属性初始化为0的时候,观察者方法并没有调用,只有外部使用改变name值的时候才调用了观察者方法.
and!
Nullable properties
All attribute variables in swift cannot be empty by default, and if unavoidable may be caused by an empty property. You need to declare it as a nullable property.
var name:string"王五花" //非空属性,此属性不可接受空值var name:string? //可空属性,此属性可以接受空值 我们主要介绍这种
The Swift hollow properties are different from the empty properties in OC, although they can be used directly name == nil
or name != nil
judged, but they cannot be assigned directly using the values inside. Here's the box concept, when a property is nullable, this property is placed in a box, This box is only empty and non-empty two states, because the property is in the box so we can not directly use this property value, need to disassemble the box man.name = name!
if not unpacking, the type of this property is the type of box.
Let man:people = people ()//initialization does not assign a value to nameifMan.name = =Nil{Print("Empty")}//Assign a value to a propertyMan.name ="Wang";Print("No value for unpacking: \ (man.name)")//Not using "!" For unpacking operationsifMan.name! =Nil{Print("value after unpacking: \ (man.name!)")//use "!" Split Package}//Use attributes to assign valuesLet str:string = man.name!;//You can also use optional accept without unpacking, optional is an enumeration variableLet op:optional = Man.name;Print("\ (OP)")Print("STR will force the unpacking operation when the value is accepted: \ (str)")
Output Result:
空没有进行拆包的值:Optional("wang")拆包以后的值:wangOptional("wang")str会在接受值的时候强制拆箱操作:wang
That is, when we declare a nullable property var name:string?
, this property is loaded by a box called, the Optional
box is allowed to empty, use the man.name == nil
statement to determine if there is no value in the box, if there is no empty, if there is not empty. Use man.name = "wang";
To store a value in the box, the value must be the same as the type at the time of declaration, when we need to use the value of the box if we use the optional value, is not the value of the box, so to use the value in the box need to use the box !
opened man.name!
before using the best judgment
There is also a state where there are properties underneath the Nullable attribute
class People: NSObject { var//People类的属性name是个可空的类型}class Name: NSObject { var English:String?//Name类中English也是可空的 var Chinese:String""//Chinese属性是不可为空的 它有一个默认值.虽然看起来和没有一样}
Use the Name property at this point to be extra careful. Although the system prompts you.
OverridefuncViewdidload () {super.viewdidload () Let man:people = people () Man.name?. Chinese ="King"The //name property does not have a value at this point, where the '? ' represents an attempt to call the Name property or the property or method after name if it is not empty Print("\ (man.name?. Chinese) ");//Output see if the above assignment will succeed: nil because the name does not have a value, then the statement after the '? ' will not be executed. The value of the output of nil is nameMan.name = name ()//Initialize nameMan.name?. Chinese ="Harry Flower"//Try again to assign a value Print("\ (man.name?. 中文版) ")//Print the Chinese property, at which time 中文版 does not have a value to the name to try to unpack, if name is not empty then use the following property result is: Nil This opens the name output is the value of the Chinese Print("\ (man.name!. Chinese) ")//Print There is a merit Chinese attribute, use here '! ' Force unpack, because we know that Anme has been initialized. Absolutely NOT NULL result is: Wang force open the value of name output Chinese at this timeMan.name?. 中文版 ="Wangwuhua" //Try to assign a value to 中文版 here you can also use '! ' Forced unpacking Print("\ (man.name?. 中文版) ")//Try calling name to unpack the English result as: Optional ("Wangwuhua") This is the value that we output is Chinese, because there is no unpacking operation so it is still Optional type Print("\ (man.name?. english!) ")//Try calling name to force unpacking the English result is: Optional ("Wangwuhua") at this time we force the solution of the English full thought will output Wangwuhua, but the result is not as we imagined, so inferred '? ' Does not have the ability to unpack, just to infer whether the Name property is empty, and thus decide whether to invoke the property under name Print("\ (man.name!. 中文版) ")//Force unpacking the name does not puzzle the English result is: Optional ("Wangwuhua") This is a better understanding. No Chinese unpacking Operation Print("\ (man.name!. english!) ")//Force unpacking the name to force unpacking the English result is: Wangwuhua finally got the desired result. All properties must be forced to be unpacked to get the final value, as if it were a set of dolls. We have to open every doll to see what's inside .}
Summarize
- The set and get methods are not created by default in swift and do not exist in the base attribute, so the set and get methods of the non-computed properties of the parent class cannot be overridden. Primarily acting on calculation of property values during write and read
- Willset and Didset are similar to KVO in OC to monitor changes in property values
- A nullable property, which can be used to
var 属性名:类名?
declare a nullable property, which means that it is ?
nullable. This system puts the property in a box and determines whether there is a value by judging whether the box is empty, if you want to use the value !
in the box To force the opening of the box. If the property below also has properties that need to 对象.属性?.属性A
be used to make a decision about whether the property is empty, if it is empty, property A is not called, if it is determined that a value can be used 对象.属性!.属性A
to get the value of property A, if property A is also a nullable type, you need to 对象.属性!.属性A!
Open each layer of box to get the value of attribute a
property of Set Get Willset Didset-! Nullable property