2014-06-10 10 views
9

में सबस्क्रिप्टिंग के माध्यम से एक्सेस गुण मेरे पास स्विफ्ट में एक कस्टम क्लास है और मैं इसकी संपत्तियों तक पहुंचने के लिए सबस्क्रिप्टिंग का उपयोग करना चाहता हूं, क्या यह संभव है?स्विफ्ट

मैं क्या चाहता हूँ कुछ इस तरह है:

class User { 
    var name: String 
    var title: String 

    subscript(key: String) -> String { 
     // Something here 
     return // Return the property that matches the key… 
    } 

    init(name: String, title: String) { 
     self.name = name 
     self.title = title 
    } 
} 

myUser = User(name: "Bob", title: "Superboss") 
myUser["name"] // "Bob" 

अद्यतन: कारण है कि मैं इस के लिए देख रहा हूँ कि मैं HTML टेम्पलेट्स से प्रस्तुत करने के लिए GRMustache उपयोग कर रहा हूँ है। मैं सिर्फ GRMustache रेंडरर करने के लिए अपने मॉडल वस्तु पारित करने में सक्षम होना चाहते हैं ...

GRMustache को हासिल करेगा बंद subscripting objectForKeyedSubscript साथ मान: और की-वैल्यू valueForKey कोडिंग विधि: विधि। कोई भी अनुकूल वस्तु टेम्पलेट्स को मूल्य प्रदान कर सकती है।

https://github.com/groue/GRMustache/blob/master/Guides/view_model.md#viewmodel-objects

+2

गुण संग्रहीत नहीं हैं के रूप में शब्दकोश तो मैं आप उन्हें उपयोग नहीं कर सकते जैसे आप चाहते हैं लगता है। 'MyUser.name' के साथ क्या गलत है? – cojoj

+0

चूंकि नाम और शीर्षक निजी नहीं हैं (क्योंकि यह अभी तक संभव नहीं है) आपको इसका कोई फायदा नहीं होगा। – Binarian

+0

मैंने इस सवाल को कुछ तर्क के साथ अपडेट किया कि मुझे ऐसा कुछ क्यों चाहिए। –

उत्तर

3

(GRMustache लेखक यहाँ)

एक तेज उन्मुख मूंछें पुस्तकालय तक बाहर है, मैं अपनी कक्षाओं NSObject से विरासत (ताकि वे valueForKey: विधि है) होने की सलाह देते हैं। फिर GRMustache इस विधि के साथ मूल्य लाएगा।

मामले यह अभी भी काम नहीं होगा (प्रतिपादन में खाली मान) में, आप को निष्क्रिय करने के GRMustache सुरक्षा सुविधाओं (https://github.com/groue/GRMustache/blob/master/Guides/security.md#disabling-safe-key-access देखें)

आप किसी भी अन्य परेशानी का अनुभव करना चाहिए कोशिश कर सकते हैं, कृपया सही भंडार में एक मुद्दा खोलने : https://github.com/groue/GRMustache/issues

2 संपादित फरवरी, 2015: GRMustache.swift बाहर है: http://github.com/groue/GRMustache.swift

2

मुझे लगता है तुम कर सकते हो:

class User { 
    let properties = Dictionary<String,String>() 

    subscript(key: String) -> String? { 
     return properties[key] 
    } 

    init(name: String, title: String) { 
     properties["name"] = name 
     properties["title"] = title 
    } 
} 

आपके उपयोग के मामले मैं होगा दृढ़ता से ऐसा करने के खिलाफ सलाह बिना जाने।

एक और दृष्टिकोण:

class User { 
    var name : String 
    var title : String 

    subscript(key: String) -> String? { 
     switch key { 
      case "name" : return name 
      case "title" : return title 
      default : return nil 
     } 
    } 

    init(name: String, title: String) { 
     self.name = name 
     self.title = title 
    } 
} 

यह ध्यान देने योग्य है कि स्विफ्ट वर्तमान में नामों से प्रतिबिंब समर्थन करने के लिए प्रकट नहीं होता है हो सकता है। reflect फ़ंक्शन Mirror देता है जिसका subscript Int आधारित है, String आधारित नहीं है।

+0

मैंने सवाल अपडेट किया कि मैं यह क्यों चाहता हूं। –

+1

मैं इस सवाल का जवाब दे रहा हूं क्योंकि मुझे लगता है कि यह सबस्क्राइबिंग, स्विच और प्रतिबिंब (या इसकी कमी) के बारे में थोड़ा सा सिखाता है। उस ने कहा, मैं उपर्युक्त में से कोई भी करने की सिफारिश नहीं करता हूं। – hpique

6

उनके नाम का उपयोग करते हुए गुण का उपयोग करने के का उपयोग करना valueForKey के लिए सक्षम होना चाहिए। सुनिश्चित करें कि आप किसी ऑब्जेक्ट के साथ काम कर रहे हैं जो NSObject

class people: NSObject { 
    var age: NSString = "44" 
    var height: NSString = "153" 
} 

let person:people = people() 

let stringVariable = "age" 

person.valueForKey("age") 
// Print "44" 

person.valueForKey("\(stringVariable)") 
// Print "44" 
+0

स्विफ्ट 3.0 के लिए: 'person.value (forKey: propertyName)' –

+1

यदि आप इसे प्राप्त करने से पहले मान मौजूद हैं तो आप चेक कैसे करते हैं? –

4

प्रतिबिंब का उपयोग करके एक हैक का एक छोटा सा है। निम्नलिखित की रेखाओं के साथ कुछ इस्तेमाल किया जा सकता है।

protocol PropertyReflectable { } 

extension PropertyReflectable { 
    subscript(key: String) -> Any? { 
     let m = Mirror(reflecting: self) 
     for child in m.children { 
      if child.label == key { return child.value } 
     } 
     return nil 
    } 
} 

struct Person { 
    let name: String 
    let age: Int 
} 

extension Person : PropertyReflectable {} 

फिर एक Person और उपयोग यह गुण keyed है बनाएँ।

let p = Person(name: "John Doe", age: 18) 

p["name"] // gives "John Doe" 
p["age"] // gives 18 

आप सबस्क्रिप्ट संशोधित हमेशा संपत्ति मूल्य का एक अंतर्वेशित स्ट्रिंग वापस जाने के लिए कर सकता है।

2

शिम का उत्तर ऊपर स्विफ्ट 4 में काम नहीं करता है। दो चीजें हैं जिनके बारे में आपको अवगत होना चाहिए।

सबसे पहले, यदि आप value(forKey:) फ़ंक्शन का उपयोग करना चाहते हैं, तो आपकी कक्षा को NSObject का उत्तराधिकारी होना चाहिए।

दूसरा, चूंकि उद्देश्य-सी को मूल्य प्रकार के बारे में कुछ भी पता नहीं है, तो आपको @objc कीवर्ड को अपने मूल्य प्रकार गुणों के सामने रखना होगा और स्विफ्ट आपके लिए भारी उठाने वाला होगा।

यहाँ उदाहरण है:

import Foundation 

class Person: NSObject { 
    @objc var name: String = "John Dow" 
    @objc var age: Int = 25 
    @objc var height: Int = 180 

    subscript(key: String) -> Any? { 
     return self.value(forKey: key) 
    } 
} 

let person: Person = Person() 

person["name"] // "John Dow" 
person["age"] // 25 
person["height"] // 180