स्विफ्ट 3 (एक्सकोड 8 बीटा 6) में रिकर्सिव प्रोटोकॉल बाधाओं की कमी के आसपास काम करना वर्तमान में "रिकर्सिव प्रोटोकॉल बाधाओं" के संबंध में एक सीमा है। here एक खुली समस्या है, और here, here और here पर समान चर्चाएं चल रही हैं। हालांकि, मैं अभी भी यह देखने में असफल रहा कि इस सीमा के आसपास किसी को कैसे काम करना चाहिए। क्या यह संभव है?स्विफ्ट 3
के एक दृश्य के चारों ओर एक दृश्य के मॉडल और अन्य तरीके से संदर्भित करने का सरल उदाहरण पर विचार करें और साथ ही किसी भी चक्र को बनाए रखने के रूप में रेफरी/मूल्य प्रकार पर विचार नहीं करने देता है:
protocol ViewModelType {
associatedtype V: ViewType
var view: V { get }
}
struct ViewModel<V: ViewType>: ViewModelType {
var view: V
}
protocol ViewType {
associatedtype VM: ViewModelType
var viewModel: VM { get }
}
struct View<VM: ViewModelType>: ViewType {
var viewModel: VM
}
ऊपर कोड आप चलेंगे साथ प्रदत्त लिंक में चर्चा के अनुसार Type may not reference itself as a requirement
में।
तब (अनुभवहीन के रूप में मैं कर रहा हूँ), मैंने सोचा कि मैं इस के आसपास करके काम कर सकता था:
protocol _ViewModelType {}
protocol ViewModelType: _ViewModelType {
associatedtype V: _ViewType
var view: V { get }
}
struct ViewModel<V: ViewType>: ViewModelType {
var view: V
}
protocol _ViewType {}
protocol ViewType: _ViewType {
associatedtype VM: _ViewModelType
var viewModel: VM { get }
}
struct View<VM: ViewModelType>: ViewType {
var viewModel: VM
}
यह त्रुटि को मारता है, लेकिन यह मूल रूप से बस समस्या स्थगित। क्योंकि अब जब हम अपने ठोस प्रकार का निर्माण करना चाहते हैं, हम विशेषज्ञता के बारे में कभी न खत्म होने पाश में खत्म हो:
let vm = ViewModel<View<ViewModel<View...>>>()
मेरा मानना है कि यह कुछ हद तक एक बुनियादी बाधा मैं अपने प्रोटोकॉल में डाल करना चाहते हैं लेकिन इस समय मैं यह देखने में असफल रहा कि इसे कैसे किया जाए। स्विफ्ट को अपडेट होने तक यह चारों ओर काम करना संभव है? या क्या मुझे स्विफ्ट में लागू होने तक कम सख्त प्रोटोकॉल शुरू करने की आवश्यकता है?
अद्यतन अगस्त 19, वर्ष 2016
इस समस्या के समाधान के लिए सबसे अच्छा तरीका यह पता लगाने की एक बहुत कोशिश के बाद, मेरा मानना है कि मैं एक समाधान है कि स्वीकार्य है और केवल पाया है कम से कम समझौते की आवश्यकता है:
protocol ViewModelType {
associatedtype D: Any // Compromise to avoid the circular protocol constraints.
var delegate: D? { get set }
}
protocol ViewType {
associatedtype VM: ViewModelType
var viewModel: VM { get }
}
protocol ViewDelegate {
func foo()
}
struct ViewModel: ViewModelType {
typealias D = ViewDelegate
var delegate: D?
func bar() {
delegate?.foo() // Access to delegate methods
}
}
struct View<VM: ViewModelType>: ViewType, ViewDelegate {
var viewModel: VM
func foo() {
// Preferred, but not possible: viewModel.delegate = self
}
}
var vm = ViewModel() // Type: ViewModel
let v = View(viewModel: vm) // Type: View<ViewModel>
vm.delegate = v
मुख्य विचार यह है कि, मध्यस्थ वस्तु या एक प्रतिनिधि वस्तु पेश की जाती है, दृश्य और दृश्य मॉडल के बीच संचार को संभालने के लिए। परिपत्र प्रोटोकॉल बाधाओं को तोड़ने के लिए इस प्रतिनिधि का संदर्भ Any
प्रकार है। जैसा कि मैंने इसे देखा है, केवल नकारात्मक पक्ष यह है कि प्रतिनिधि को "बाहरी से" स्थापित करने की आवश्यकता होती है, जहां से वस्तुओं को बनाया जाता है, और View
कार्यान्वयन में सेट नहीं किया जा सकता है। अगर कोई ऐसा करने का प्रयास करता है, तो त्रुटि Cannot assign value of type View<VM> to type _?
दिखाई देगी।
हालांकि, इस दृष्टिकोण के साथ हमें बहुत सारी विशेषज्ञता के बिना सही प्रकार मिलते हैं। बेशक, कोई और अधिक अवशोषण के लिए अधिक प्रोटोकॉल जोड़ सकता है, लेकिन एक ही समाधान लागू होगा।
यह बेहतर है, धन्यवाद! मुझे लगता है, यह करीब है क्योंकि हम स्विफ्ट के वर्तमान संस्करण के साथ मिल सकते हैं। –