Introduction and use of Swift-reflection (Reflection) for iOS development (with KVC Introduction)

Source: Internet
Author: User
Tags reflection

1, Reflection (Reflection)
For C # and Java developers, it is certainly quite familiar with the concept of reflection. The so-called reflection is the dynamic access to the type, member information, while at run time (but not compile time) can dynamically invoke arbitrary methods, attributes and other behavior characteristics.
Take the two well-known frameworks in Java (Hibernate and spring) for example. Hibernate's property mappings are assigned by reflection, and the spring Bean's creation is based on the configured class to reflect the build.

2,objective-c's Runtime
The concept of reflection is rarely emphasized when using OBJC development because the runtime of OBJC is much stronger than the reflection in other languages. In OBJC, it is easy to implement string and type conversions (Nsclassfromstring ()), implement dynamic method invocation (Performselector:withobject:), dynamic Assignment (KVC), and so on.

Reflection in the 3,swift
It is not advocated in swift to use runtime, but to use reflection (reflect) as in other languages. Of course, the current reflection in Swift is not as powerful as the reflection in other languages, not only far less than the runtime of OC, but also a certain distance from the reflection of Java.
Swift's reflection mechanism is implemented based on a struct called Mirror, which has the following properties and methods:


The child node of Let Children:children//object.
DisplayStyle:Mirror.DisplayStyle? The presentation style of the object
Let SubjectType:Any.Type//object type
Func superclassmirror ()-> Mirror? Mirror of Object parent class

Examples of the use of 4,swift reflection

Sample 1: Outputs the class name of the entity object, the number of attributes, and the property names and property values of all properties.
First, define a user class:


User class
Class User {
var name:string = ""/Name
var nickname:string? Nickname
var age:int? Age
var emails:[string]? Mailing Address
}

It then creates a user object and retrieves the object's information through reflection:


Create a user instance object
Let User1 = User ()
User1.name = "Hangge"
User1.age = 100
User1.emails = ["hangge@hangge.com", "system@hangge.com"]

To reflect a user object
Let Hmirror = Mirror (reflecting:user1)

Print ("Object type: \ (hmirror.subjecttype)")
Print ("Number of object child elements: \ (hMirror.children.count)")

Print (the property name and property values of the---object child elements are as follows---)
For case let (label., value) in Hmirror.children {
Print ("Properties: \ (label) value: \ (value)")
}

The console output information is as follows:

Sample 2: Gets the corresponding property value through the property name (string) and makes a type judgment on the value (including whether it is empty)
First for ease of use, here is a definition of two methods. Getvaluebykey () is used to get the corresponding property value in an object based on the Passed-in property name string. Unwrap () is used to disassemble the optional type (return the original value for a non-optional type)


///Get property value based on property name String
Func getvaluebykey (Obj:anyobject, key:string)-> any {
    let Hmirror = Mirror (reflecting:obj)
    for Case let (label., value) in Hmirror.children {
    ;     if label = = key {
            return unwrap (value)
       }
   }
     return Nsnull ()
}
 
//Unpacking optional type (Optional)
Func Unwrap (any:any)-> any {
  &nbs P Let mi = Mirror (reflecting:any)
    if Mi.displaystyle!=. Optional {
        return any
   }
   & nbsp
    If Mi.children.count = 0 {return no}
    Let (_, some) = mi.children.first!
    return some
}

Here is the actual test sample, which is also tested with the user object in the previous example:


Create a user instance object
Let User1 = User ()
User1.name = "Hangge"
User1.age = 100
User1.emails = ["hangge@hangge.com", "system@hangge.com"]

Get the corresponding value through the property name string
Let name = Getvaluebykey (user1, Key: "Name")
Let nickname = Getvaluebykey (user1, Key: "nickname")
Let-age = Getvaluebykey (user1, Key: ' Age ')
Let emails = Getvaluebykey (user1, key: "Emails")
Let Tel = getvaluebykey (user1, Key: "Tel")
Print (name, nickname, age, emails, tel)

Of course, you can also make type judgments about the values you get
If name is Nsnull {
Print ("Name this property does not exist")
}else if (name as?) Anyobject) = = Nil {
Print ("Name This property is an optional type and is nil")
}else If name is String {
Print ("Name" is the property string type with the value: \ (name))
}

If nickname is Nsnull {
Print ("Nickname this property does not exist")
}else if (nickname as?) Anyobject) = = Nil {
Print ("Nickname this property is an optional type and is nil")
}else If nickname is String {
Print ("Nickname this property string, whose value is: \ (nickname)")
}

If Tel is nsnull {
Print ("Tel This property does not exist")
}else if (tel as? Anyobject) = = Nil {
Print ("Tel This property is an optional type and is nil")
}else If Tel is String {
Print ("Tel this property string type with a value of: \ (tel)")
}

The console output information is as follows:

Attachment: Access to property values via KVC
KVC is the abbreviation of key-value coding. It is a mechanism for indirectly accessing objects. Its essence is based on the strong dynamic ability of runtime in OC. In Swift, KVC can be used as long as the class inherits NSObject. (There is a call KVO, it is based on KVC, we are interested in the study under their own.) )
KVC: The value of the key is the string of the attribute name, and the value returned is any type and needs to be converted to the desired type.
(Note: Because KVC is based on objective-c, it does not support attributes of the optional type (optional), such as the Var age:int in the previous example?
So the user class does the following makeover:


User class
Class user:nsobject{
var name:string = ""/Name
var nickname:string? Nickname
var age:int = 0//Age
var emails:[string]? Mailing Address
}

KVC is mainly two methods:

(1) The corresponding property value is obtained by key


Create a user instance object
Let User1 = User ()
User1.name = "Hangge"
User1.age = 100
User1.emails = ["hangge@hangge.com", "system@hangge.com"]

Using KVC to take values
Let name = User1.valueforkey ("name")
Let nickname = User1.valueforkey ("nickname")
Let-age = User1.valueforkey (' age ')
Let emails = user1.valueforkey ("emails")
Let Tel = User1.valueforkey ("tel")
Print (name, nickname, age, emails)


Of course, you can also make type judgments about the values you get
If name = = Nil {
Print ("Name This property is an optional type and is nil")
}else If name is String {
Print ("Name" is the property string type with the value: \ (name))
}

If nickname = = Nil {
Print ("Nickname this property is an optional type and is nil")
}else If nickname is String {
Print ("Nickname this property string, whose value is: \ (nickname)")
}


(2) Set the corresponding property value by key


Create a user instance object
Let User1 = User ()

Using KVC Assignment
User1.setvalue ("Hangge", Forkey: "Name")
User1.setvalue (forkey: "Age")
User1.setvalue (["hangge@hangge.com", "system@hangge.com"], Forkey: "Emails")

Print (User1.name, User1.nickname, User1.age, User1.emails)

Original source: www.hangge.com reprint please keep the original link: http://www.hangge.com/blog/cache/detail_976.html

Related Article

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.