खोज…


वाक्य - विन्यास

  • दर्पण (प्रतिबिंबित करना: उदाहरण) // प्रतिबिंबित करने के लिए विषय के साथ एक दर्पण शुरू करता है
  • mirror.displayStyle // Xcode खेल के मैदानों के लिए उपयोग की जाने वाली प्रदर्शन शैली
  • mirror.description // इस उदाहरण का शाब्दिक प्रतिनिधित्व, CustomStringConvertible देखें
  • मिरर.सुबजेक्टटाइप // परिलक्षित होने वाले विषय के प्रकार को लौटाता है
  • दर्पण.सुपरक्लास मिरर // परिलक्षित होने वाले विषय के सुपर-क्लास का दर्पण देता है

टिप्पणियों

  1. सामान्य टिप्पणियाँ:

एक Mirror एक struct जिसका उपयोग स्विफ्ट में किसी वस्तु के आत्मनिरीक्षण में किया जाता है। इसकी सबसे प्रमुख संपत्ति बच्चों की सरणी है। Core Data लिए एक संरचना को क्रमबद्ध करना एक संभव उपयोग मामला है। यह NSManagedObject में एक struct को परिवर्तित करके किया जाता है।

  1. दर्पण के लिए मूल उपयोग

Mirror की children संपत्ति ऑब्जेक्ट की एक ऐसी वस्तु है, जिससे मिरर का उदाहरण प्रतिबिंबित होता है। एक child ऑब्जेक्ट में दो गुण label और value । उदाहरण के लिए एक बच्चा नाम title और Game of Thrones: A Song of Ice and Fire साथ एक संपत्ति हो सकता है।

दर्पण के लिए बुनियादी उपयोग

दर्पण का विषय बनने के लिए कक्षा का निर्माण करना

class Project {
    var title: String = ""
    var id: Int = 0
    var platform: String = ""
    var version: Int = 0
    var info: String?
}

एक उदाहरण बनाना जो वास्तव में दर्पण का विषय होगा। यहाँ भी आप प्रोजेक्ट क्लास की संपत्तियों में मूल्य जोड़ सकते हैं।

let sampleProject = Project()
sampleProject.title = "MirrorMirror"
sampleProject.id = 199
sampleProject.platform = "iOS"
sampleProject.version = 2
sampleProject.info = "test app for Reflection"

नीचे दिया गया कोड मिरर इंस्टेंस का निर्माण दिखाता है। दर्पण के बच्चों की संपत्ति एक AnyForwardCollection<Child> जहां Child विषय की संपत्ति और मूल्य के लिए टाइपेलियस ट्यूपल है। Child पास एक label: String और value: Any

let projectMirror = Mirror(reflecting: sampleProject)
let properties = projectMirror.children

print(properties.count)        //5
print(properties.first?.label) //Optional("title")
print(properties.first!.value) //MirrorMirror
print()

for property in properties {
    print("\(property.label!):\(property.value)")
}

ऊपर के लूप के लिए Xcode में प्लेग्राउंड या कंसोल में आउटपुट।

title:MirrorMirror
id:199
platform:iOS
version:2
info:Optional("test app for Reflection")

Xcode 8 बीटा 2 पर प्लेग्राउंड में परीक्षण किया गया

एक वर्ग के लिए गुणों के प्रकार और नाम प्राप्त करना, बिना उसे तुरंत बताए

यदि आप किसी निश्चित वर्ग के उदाहरण के लिए गुणों का नाम , मान और प्रकार (स्विफ्ट 3: type(of: value) , स्विफ्ट 2: value.dynamicType ) का उपयोग करना चाहते हैं, तो स्विफ्ट क्लास Mirror का उपयोग करना।

यदि आप क्लास NSObject से इनहेरिट करते हैं, तो आप class_copyPropertyList उपयोग property_getAttributes class_copyPropertyList साथ एक वर्ग के लिए नाम और प्रकार की संपत्तियों का पता लगाने के लिए कर सकते हैं - बिना इसका उदाहरण दिए । मैंने इसके लिए गितुब पर एक प्रोजेक्ट बनाया, लेकिन यहाँ कोड है:

func getTypesOfProperties(in clazz: NSObject.Type) -> Dictionary<String, Any>? {
    var count = UInt32()
    guard let properties = class_copyPropertyList(clazz, &count) else { return nil }
    var types: Dictionary<String, Any> = [:]
    for i in 0..<Int(count) {
        guard let property: objc_property_t = properties[i], let name = getNameOf(property: property) else { continue }
        let type = getTypeOf(property: property)
        types[name] = type
    }
    free(properties)
    return types
}

func getTypeOf(property: objc_property_t) -> Any {
    guard let attributesAsNSString: NSString = NSString(utf8String: property_getAttributes(property)) else { return Any.self }
    let attributes = attributesAsNSString as String
    let slices = attributes.components(separatedBy: "\"")
    guard slices.count > 1 else { return getPrimitiveDataType(withAttributes: attributes) }
    let objectClassName = slices[1]
    let objectClass = NSClassFromString(objectClassName) as! NSObject.Type
    return objectClass
}
    
   func getPrimitiveDataType(withAttributes attributes: String) -> Any {
        guard let letter = attributes.substring(from: 1, to: 2), let type = primitiveDataTypes[letter] else { return Any.self }
        return type
    }

जहाँ primitiveDataTypes एक अक्षर होता है जो विशेषता स्ट्रिंग में एक अक्षर को मान प्रकार में मैप करता है:

let primitiveDataTypes: Dictionary<String, Any> = [
    "c" : Int8.self,
    "s" : Int16.self,
    "i" : Int32.self,
    "q" : Int.self, //also: Int64, NSInteger, only true on 64 bit platforms
    "S" : UInt16.self,
    "I" : UInt32.self,
    "Q" : UInt.self, //also UInt64, only true on 64 bit platforms
    "B" : Bool.self,
    "d" : Double.self,
    "f" : Float.self,
    "{" : Decimal.self
]
    
   func getNameOf(property: objc_property_t) -> String? {
        guard let name: NSString = NSString(utf8String: property_getName(property)) else { return nil }
        return name as String
    }

यह NSObject.Type के सभी गुणों को निकाल सकता है, जो NSDate (Swift3: Date ), NSString (Swift3: String ?) और NSNumber जैसे NSObject से इनहेरिट की जाती है, हालाँकि यह Any प्रकार में स्टोर हो सकती है (जैसा कि आप देख सकते हैं) विधि द्वारा लौटाए गए शब्दकोश के मूल्य का प्रकार)। यह Int, Int32, बूल जैसे value types की सीमाओं के कारण है। के बाद से उन प्रकार NSObject से विरासत नहीं है, बुला .self एक इंट जैसे पर - Int.self NSObject.Type वापस नहीं करता है, बल्कि प्रकार Any । इस प्रकार विधि Dictionary<String, Any>? लौटाती है Dictionary<String, Any>? और Dictionary<String, NSObject.Type>?

आप इस विधि का उपयोग इस तरह कर सकते हैं:

class Book: NSObject {
    let title: String
    let author: String?
    let numberOfPages: Int
    let released: Date
    let isPocket: Bool

    init(title: String, author: String?, numberOfPages: Int, released: Date, isPocket: Bool) {
        self.title = title
        self.author = author
        self.numberOfPages = numberOfPages
        self.released = released
        self.isPocket = isPocket
    }
}

guard let types = getTypesOfProperties(in: Book.self) else { return }
for (name, type) in types {
    print("'\(name)' has type '\(type)'")
}
// Prints:
// 'title' has type 'NSString'
// 'numberOfPages' has type 'Int'
// 'author' has type 'NSString'
// 'released' has type 'NSDate'
// 'isPocket' has type 'Bool'

आप Any NSObject.Type को कास्ट करने का प्रयास कर सकते हैं, जो NSObject से विरासत में मिली सभी संपत्तियों के लिए सफल होगा, फिर आप मानक == ऑपरेटर का उपयोग करके प्रकार की जांच कर सकते हैं:

func checkPropertiesOfBook() {
    guard let types = getTypesOfProperties(in: Book.self) else { return }
    for (name, type) in types {
        if let objectType = type as? NSObject.Type {
            if objectType == NSDate.self {
                print("Property named '\(name)' has type 'NSDate'")
            } else if objectType == NSString.self {
                print("Property named '\(name)' has type 'NSString'")
            }
        }
    }
}

यदि आप इस रिवाज की घोषणा करते हैं == ऑपरेटर:

func ==(rhs: Any, lhs: Any) -> Bool {
    let rhsType: String = "\(rhs)"
    let lhsType: String = "\(lhs)"
    let same = rhsType == lhsType
    return same
}

फिर आप इस प्रकार के value types भी देख सकते हैं:

func checkPropertiesOfBook() {
    guard let types = getTypesOfProperties(in: Book.self) else { return }
    for (name, type) in types {
        if type == Int.self {
            print("Property named '\(name)' has type 'Int'")
        } else if type == Bool.self {
            print("Property named '\(name)' has type 'Bool'")
        }
    }
}

सीमाएँ यह समाधान तब काम नहीं करता है जब value types वैकल्पिक value types हैं। यदि आप में एक संपत्ति की घोषणा की है NSObject उपवर्ग इस तरह: var myOptionalInt: Int? उपरोक्त कोड को वह संपत्ति नहीं मिलेगी क्योंकि विधि class_copyPropertyList में वैकल्पिक मान प्रकार नहीं होते हैं।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow