क्या स्विफ्ट सपोर्ट रिफ्लेक्ट करता है?


113

क्या स्विफ्ट सपोर्ट रिफ्लेक्ट करता है? जैसे वहाँ valueForKeyPath:और setValue:forKeyPath:स्विफ्ट वस्तुओं के लिए कुछ है ?

वास्तव में यह भी एक गतिशील प्रकार प्रणाली है, obj.classउद्देश्य सी में कुछ की तरह ?


1
मैंने स्विफ्ट में प्रतिबिंब के लिए एक सहायक वर्ग बनाया। आप इसे यहां देख सकते हैं: github.com/evermeer/EVReflection
एडविन वर्मर

2
उन्होंने स्विफ्ट 2.0 के भीतर प्रतिबिंबित को हटा दिया है। यह है कि मैं कैसे विशेषताओं और मूल्यों को मान रहा हूँ लिंक
mohacs

जवाबों:


85

ऐसा लगता है कि कुछ प्रतिबिंब समर्थन की शुरुआत है:

class Fruit {
    var name="Apple"
}

reflect(Fruit()).count         // 1
reflect(Fruit())[0].0          // "name"
reflect(Fruit())[0].1.summary  // "Apple"

Mchambers gist से, यहाँ: https://gist.github.com/mchambers/fb9da554898dae3e54f2


5
खैर, मैं इसे वास्तविक प्रतिबिंब नहीं मानूंगा। एक बात के लिए, यह आसानी से है। मुझे लगता है कि यह Xcode में डिबगिंग को सक्षम करने के लिए सिर्फ एक हैक है। प्रोटोकॉल Mirrorवास्तव में शब्द को IDEकई बार उद्धृत करता है ।
सुल्तान

7
और यह केवल गुणों के लिए काम करता है। कोई विधि प्रतिबिंब नहीं।
सुल्तान

11
जिस्ट चेकिंग के लेखक। मैंने इसे डब्ल्यूडब्ल्यूडीसी की स्विफ्ट लैब में लिखा, मुझे लगा कि मैं इसका बाकी हिस्सा साझा करूंगा। जैसा कि सभी को पता है, मैंने जिन इंजीनियरों के साथ बात की थी, वे इस बात की पुष्टि करते हैं कि प्लेग्राउंड को सपोर्ट करने के लिए फंक्शन मौजूद हैं। लेकिन आप अभी भी इसके साथ कुछ मज़ेदार हो सकते हैं :) यहाँ मैंने इसका उपयोग करते हुए एक छोटे मॉडल धारावाहिक को हैक किया है। इसे खेल के मैदान में पेस्ट करें और मज़े करें: gist.github.com/mchambers/67640d9c3e2bcffbb1e2
Marc Chambers

1
कैसे मदद कर सकते हैं, यह जानने के लिए उत्तर stackoverflow.com/a/25345461/292145 पर एक नज़र डालें _stdlib_getTypeName
कालस

1
यहाँ एक वर्ग है जो बेस क्लास और अल्टरनेटिव्स (टाइप्स नहीं) का प्रतिबिंब देगा और इसमें NSCoding और पार्सिंग के लिए और एक शब्दकोश से समर्थन है: github.com/evermeer/EVCloudKitDao/blob-master-AppMessage/…
एडविन

44

यदि एक वर्ग का विस्तार होता है NSObject, तो सभी उद्देश्य-सी के आत्मनिरीक्षण और गतिशीलता का काम करते हैं। यह भी शामिल है:

  • किसी वर्ग से उसके तरीकों और गुणों के बारे में पूछने और विधियों को लागू करने या गुणों को निर्धारित करने की क्षमता।
  • विधि कार्यान्वयन को आदान-प्रदान करने की क्षमता। (सभी उदाहरणों के लिए कार्यक्षमता जोड़ें)।
  • मक्खी पर एक नया उप-वर्ग उत्पन्न करने और असाइन करने की क्षमता। (किसी दिए गए उदाहरण में कार्यक्षमता जोड़ें)

इस कार्यक्षमता की एक कमी स्विफ्ट वैकल्पिक मूल्य प्रकारों के लिए समर्थन है। उदाहरण के लिए Int गुण एनुमरेट और संशोधित किए जा सकते हैं लेकिन Int? गुण नहीं कर सकते। वैकल्पिक प्रकार को प्रतिबिंबित / मिरर टाइप का उपयोग करके आंशिक रूप से गणना की जा सकती है, लेकिन फिर भी संशोधित नहीं किया गया है।

यदि कोई वर्ग विस्तार नहीं करता है NSObject, तो केवल नया, बहुत सीमित (और प्रगति में है) प्रतिबिंब कार्य करता है (प्रतिबिंबित / मिरर टाइप देखें), जो अपनी कक्षा और गुणों के बारे में एक उदाहरण पूछने की सीमित क्षमता को जोड़ता है, लेकिन उपरोक्त अतिरिक्त विशेषताओं में से कोई भी नहीं। ।

जब NSObject का विस्तार नहीं किया जाता है, या '@objc' निर्देश का उपयोग करते हुए, स्विफ्ट डिफॉल्ट को स्थैतिक- और व्यवहार्य-आधारित प्रेषण में बदल देता है। यह तेज़ है, हालाँकि, वर्चुअल मशीन की अनुपस्थिति में रनटाइम विधि अवरोधन की अनुमति नहीं है। यह अवरोधन कोको का एक मूलभूत हिस्सा है और निम्न प्रकार की विशेषताओं के लिए आवश्यक है:

  • कोको की सुंदर संपत्ति पर्यवेक्षक। (संपत्ति पर्यवेक्षकों को स्विफ्ट भाषा में सही बेक किया गया है)।
  • लॉग-इन, लेन-देन प्रबंधन (यानी पहलू ओरिएंटेड प्रोग्रामिंग) जैसे गैर-इनवेसिव रूप से क्रॉस-कटिंग चिंताओं को लागू करना।
  • परदे के पीछे, संदेश अग्रेषण, आदि।

इसलिए इसकी सिफारिश की गई है कि स्विफ्ट के साथ लागू कोको / कोकोआटौक्स अनुप्रयोगों में क्लैस:

  • NSObject से विस्तार करें। इस दिशा में Xcode में नया वर्ग संवाद है।
  • जहां एक गतिशील प्रेषण के ओवरहेड प्रदर्शन के मुद्दों की ओर जाता है, तो स्थैतिक प्रेषण का उपयोग किया जा सकता है - बहुत छोटे निकायों के साथ विधियों के लिए कॉल के साथ तंग छोरों में, उदाहरण के लिए।

सारांश:

  • स्विफ्ट सी ++ की तरह व्यवहार कर सकता है, तेज स्थैतिक / व्यवहार्य प्रेषण और सीमित प्रतिबिंब के साथ। यह निचले स्तर या प्रदर्शन गहन अनुप्रयोगों के लिए उपयुक्त बनाता है, लेकिन जटिलता के बिना, सीखने की अवस्था या C ++ से जुड़ी त्रुटि का जोखिम
  • जबकि स्विफ्ट एक संकलित भाषा है, मेथड इंवोकेशन की मैसेजिंग शैली ऑब्जेक्टिव-सी की तरह ही रूबी और पायथन जैसी आधुनिक भाषाओं में पाई जाने वाली आत्मनिरीक्षण और गतिशीलता को जोड़ती है, लेकिन ऑब्जेक्टिव-सी की विरासत सिंटैक्स के बिना।

संदर्भ डेटा: विधि चालान के लिए निष्पादन ओवरहेड:

  • स्थिर: <1.1ns
  • व्यवहार्य: ~ 1.1ns
  • गतिशील: ~ 4.9ns

(वास्तविक प्रदर्शन हार्डवेयर पर निर्भर करता है, लेकिन अनुपात समान रहेगा)।

इसके अलावा, गतिशील विशेषता हमें स्विफ्ट को स्पष्ट रूप से निर्देश देने की अनुमति देती है कि एक विधि को गतिशील प्रेषण का उपयोग करना चाहिए, और इसलिए अवरोधन का समर्थन करेगा।

public dynamic func foobar() -> AnyObject {
}

2
ऑब्जेक्टिव-सी तकनीकों का उपयोग करते हुए भी यह वैकल्पिक स्विफ्ट प्रकारों के लिए काम नहीं करता है। मैं जवाब में इस सीमा को नोट करने का सुझाव दूंगा जब तक कि मुझे कोई ट्रिक याद न हो।
वाइटनीलैंड

8

प्रलेखन मुख्य रूप से के बारे में एक गतिशील प्रकार प्रणाली के बारे में बोलता है

Type तथा dynamicType

देख मेटाटाइप प्रकार (भाषा संदर्भ में)

उदाहरण:

var clazz = TestObject.self
var instance: TestObject = clazz()

var type = instance.dynamicType

println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"

अब मान लिया गया TestObjectहैNSObject

var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()

if let testObject = instance as? TestObject {
    println("yes!") //prints "yes!"
}

वर्तमान में, कोई प्रतिबिंब लागू नहीं है।

संपादित करें: मैं जाहिरा तौर पर गलत था, स्टीववे का जवाब देखें। में निर्मित गुणों के लिए कुछ सरल पढ़ने योग्य प्रतिबिंब है, शायद आईडीई को ऑब्जेक्ट सामग्री का निरीक्षण करने की अनुमति देता है।


6

ऐसा लगता है कि एक स्विफ्ट प्रतिबिंब एपीआई इस समय एप्पल के लिए एक उच्च प्राथमिकता नहीं है। लेकिन @stevex जवाब के अलावा मानक पुस्तकालय में एक और कार्य है जो मदद करता है।

बीटा 6 के रूप में _stdlib_getTypeNameएक चर का नाम टाइप प्रकार प्राप्त होता है। इसे एक खाली खेल के मैदान में चिपकाएँ:

import Foundation

class PureSwiftClass {
}

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

println( "TypeName0 = \(_stdlib_getTypeName(myvar0))")
println( "TypeName1 = \(_stdlib_getTypeName(myvar1))")
println( "TypeName2 = \(_stdlib_getTypeName(myvar2))")
println( "TypeName3 = \(_stdlib_getTypeName(myvar3))")

आउटपुट है:

TypeName0 = NSString
TypeName1 = _TtC13__lldb_expr_014PureSwiftClass
TypeName2 = _TtSi
TypeName3 = _TtSS

इवान स्विक की ब्लॉग प्रविष्टि इन तारों को समझने में मदद करती है:

उदाहरण _TtSiके लिए स्विफ्ट का आंतरिक Intप्रकार है।

माइक ऐश के पास एक ही विषय को कवर करने वाली एक महान ब्लॉग प्रविष्टि है


@aleclarson हाँ, यह भी काफी उपयोगी है।
कालस

1
क्या वे निजी API नहीं हैं? यदि ऐप का उपयोग किया जाता है, तो क्या ऐप अनुमोदन करेगा?
एडुआर्डो कोस्टा

@EduardoCosta हाँ, निश्चित रूप से। वे निजी हैं। मैं केवल डिबग बिल्ड के लिए उनका उपयोग करता हूं।
काल

इवान स्विक
RenniePet

5

आप इसके बजाय toString () का उपयोग करने पर विचार करना चाह सकते हैं । यह सार्वजनिक है और के रूप में सिर्फ एक ही काम करता है () _stdlib_getTypeName अंतर यह है कि यह भी पर काम करता है के साथ AnyClass एक खेल का मैदान में, उदाहरण के लिए प्रवेश

class MyClass {}

toString(MyClass.self) // evaluates to "__lldb_expr_49.MyClass"

1

reflectस्विफ्ट 5 में कोई कीवर्ड नहीं , अब आप उपयोग कर सकते हैं

struct Person {
    var name="name"
    var age = 15
}

var me = Person()
var mirror = Mirror(reflecting: me)

for case let (label?, value) in mirror.children {
    print (label, value)
}

इसे क्यों नहीं उखाड़ा गया? यह v उपयोगी है। मैं इसे jsondeserialization के लिए लागू करने जा रहा हूं
javadba
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.