2015-12-16 14 views
5

में लूप के अंदर ऑब्जेक्ट की प्रॉपर्टी बदलना मैंने शॉपिंगलिस्ट नामक एक साधारण स्ट्रक्चर बनाई है।स्विफ्ट

struct ShoppingList { 

    var shoppingListId :NSNumber 
    var title :String 
    var groceryItems :[GroceryItem] 

    init() { 
     self.title = "" 
     self.groceryItems = [GroceryItem]() 
     self.shoppingListId = NSNumber(integer: 0) 
    } 

} 

अगला मैं इस तरह एक ShoppingList सरणी बनाया:

var shoppingLists = [ShoppingList]() 

उसके बाद मैं अब खरीदारी सूचियों आदि लाने, मैं shoppingLists के माध्यम से पुनरावृति और शीर्षक बदलने, लेकिन यह कभी शीर्षक संपत्ति अद्यतन करता है ।

for var shoppingList in shoppingLists { 
    let items = getGroceryItemsByShoppingList(shoppingList) 
    shoppingList.groceryItems = getGroceryItemsByShoppingList(shoppingList) 
    shoppingList.title = "BLAH" // copied by value 
    print("ShoppingList \(shoppingList.title) has \(shoppingList.groceryItems.count) items") // THIS PRINT BLAH 
} 

print("shoppingLists[0].groceryItems.count \(shoppingLists[0].groceryItems.count)") // THIS PRINTS THE ORIGINAL CONTENT 

मेरा मानना ​​है कि जब मैं लूप चला रहा हूं तो यह मूल्य से प्रतिलिपि बना रहा है और इसलिए मूल सरणी कभी नहीं बदली जाती है। फॉर लूप का उपयोग करके मैं मूल सरणी कैसे बदल सकता हूं?

+0

एक स्पष्ट और संक्षिप्त प्रश्न पोस्ट करने के लिए धन्यवाद, आपने डेवलपर्स में अपना विश्वास नवीनीकृत कर दिया है। – RyanR

उत्तर

7

दो दृष्टिकोण हैं जिनका मैं यहां उपयोग करूंगा। पहला दृष्टिकोण पुनर्विचार करना है कि ShoppingList एक मान प्रकार या संदर्भ प्रकार है या नहीं। तथ्य यह है कि इसमें एक पहचानकर्ता है जो मुझे बताता है कि यह वास्तव में एक संदर्भ प्रकार है। यदि दो शॉपिंग सूचियों में एक ही सामग्री है, तो क्या एक ही सूची माना जाना चाहिए? मुझे संदेह नहीं है। दो सूचियों का मतलब क्या होगा जिनके समान पहचानकर्ता है, लेकिन अलग-अलग सामग्री? यदि यह गैरकानूनी है, तो यह एक संदर्भ प्रकार होने के लिए इंगित करता है क्योंकि इसकी पहचान है।

यदि यह एक संदर्भ प्रकार है, यह एक final class बनाने:

final class ShoppingList {} 

अंतिम कक्षाएं structs की सादगी को बनाए रखने के कारण वे विरासत की समस्याओं ग्रस्त नहीं है। लेकिन वे संदर्भ अर्थशास्त्र प्रदान करते हैं। उस परिवर्तन के साथ, आपका मूल कोड काम करेगा।

इस तक पहुंचने का दूसरा तरीका अधिक कार्यात्मक है, जहां सब कुछ एक मूल्य है। उस मामले में, आप अपनी खरीदारी सूचियों की प्रतियां मैप करके इस लक्ष्य को हासिल कर सकते हैं:

shoppingLists = shoppingLists.map { list in 
    var newList = list 
    newList.groceryItems = getGroceryItemsByShoppingList(list) 
    return newList 
} 

यह एक अधिक कार्यात्मक दृष्टिकोण की दिशा में हमें धक्का है, लेकिन यह पहचानकर्ता अजीब बना देता है। तो यदि आप वास्तव में इस तरह से जाना चाहते थे, तो मैं पहचानकर्ताओं से छुटकारा पाना चाहता हूं और यहां तक ​​कि शॉपिंग सूचियां भी अपरिवर्तनीय बना सकता हूं। उस स्थिति में, किसी भी दो समान खरीदारी सूचियां एक ही सूची हैं, और आप एक और अधिक कार्यात्मक शैली में लिख सकते हैं।

लेकिन मुझे संदेह है कि ShoppingList एक संदर्भ प्रकार आपके बेहतर दृष्टिकोण है।

+0

मुझे वास्तव में मूल्य बनाम रेफ प्रकारों पर आपका तर्क पसंद है। चूंकि शॉपिंग सूची में एक पहचान है (शॉपिंगलिस्ट आईडी) जैसा कि आपने सुझाव दिया है, इसे एक रेफ प्रकार के रूप में रखना बेहतर है। –

1

ठीक है, मैंने इसे समझ लिया। ऐसा लगता है कि अब आप जिस तरह से करते हैं वह एक संदर्भ बना रहा है और लूप के अंदर अपनी गुणों को बदल रहा है (जो संरचनाओं के मामले में मूल उदाहरण नहीं बदलता है)। आपको इसके बजाय क्या करना चाहिए इसके बजाय उन्हें सीधे कॉल करें:

for index in 0..<shoppingLists.count { 

//Stuff you do. Do the same way, just replace "shoppingList" to "shoppingLists[index]" 

shoppingLists[index].title = "BLAH" // copied by value 
    print("ShoppingList \(shoppingLists[index].title) has items") // THIS PRINT BLAH 

} 

print("shoppingLists[0].groceryItems.title: \(shoppingLists[0].title)") // Returns "shoppingLists[0].groceryItems.title: BLAH" 

यह काम करता है, मैंने जांच की है, आपका स्वागत है!

+0

यदि आप "var" को छोड़ देते हैं तो आप उदाहरण का इलाज कर रहे हैं "चलो" जिसका मतलब निरंतर है और आप स्थिर नहीं बदल सकते हैं। –

+0

फिर भी आप अभी भी अपनी संपत्तियों को बदल सकते हैं, आदमी – EBDOKUM

+0

यदि यह एक संरचना नहीं है! –