Swift Language
प्रतिबिंब
खोज…
वाक्य - विन्यास
- दर्पण (प्रतिबिंबित करना: उदाहरण) // प्रतिबिंबित करने के लिए विषय के साथ एक दर्पण शुरू करता है
- mirror.displayStyle // Xcode खेल के मैदानों के लिए उपयोग की जाने वाली प्रदर्शन शैली
- mirror.description // इस उदाहरण का शाब्दिक प्रतिनिधित्व, CustomStringConvertible देखें
- मिरर.सुबजेक्टटाइप // परिलक्षित होने वाले विषय के प्रकार को लौटाता है
- दर्पण.सुपरक्लास मिरर // परिलक्षित होने वाले विषय के सुपर-क्लास का दर्पण देता है
टिप्पणियों
- सामान्य टिप्पणियाँ:
एक Mirror
एक struct
जिसका उपयोग स्विफ्ट में किसी वस्तु के आत्मनिरीक्षण में किया जाता है। इसकी सबसे प्रमुख संपत्ति बच्चों की सरणी है। Core Data
लिए एक संरचना को क्रमबद्ध करना एक संभव उपयोग मामला है। यह NSManagedObject
में एक struct
को परिवर्तित करके किया जाता है।
- दर्पण के लिए मूल उपयोग
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
में वैकल्पिक मान प्रकार नहीं होते हैं।