2015-09-18 12 views
7

मैंने स्विफ्ट आईओएस ऐप में सीक्यूआरएस पैटर्न को लागू करने की कोशिश की और मुझे अजीब व्यवहार मिला।स्विफ्ट - जेनेरिक समस्या कारण स्मृति रिसाव

कोर कक्षाएं:

class Query<T> {} 

class QueryHandler<TResult, TQuery:Query<TResult>> { 

    func execute(query: TQuery, callback: (result: TResult) -> Void) { 
    } 
} 

को लागू करने कक्षाएं:

class GetRandomStringsQuery: Query<[String]> { 
internal var prefix:String 

init(prefix: String) { 
    self.prefix = prefix 
    } 
} 

class GetRandomStringsQueryHandler: QueryHandler<[String], GetRandomStringsQuery> { 

    override func execute(query: GetRandomStringsQuery, callback: (result: [String]) -> Void) { 
     var result = [String]() 

     for var i = 0; i < 100; i++ { 
      result.append("[\(i)]: \(query.prefix)") 
     } 

     callback(result: result) 
    } 
} 

उदाहरण उपयोग:

@IBAction func generateMemoryLeak(sender: AnyObject) { 
     let query = GetRandomStringsQuery(prefix: "leak leak leak :(") 

     let queryHandler = GetRandomStringsQueryHandler() 

     queryHandler.execute(query) { (result) -> Void in 
      print("total records: \(result.count)") 
     } 
} 

कॉलबैक में हम सरणी में 100 तत्वों मिलना चाहिए। रनटाइम पर ऐसा लगता है कि संदर्भ गुम हो गया है और मान अज्ञात है। आईओएस डेवलपर इंस्ट्रूमेंट्स मेमोरी लीक का पता लगाता है।

वीड व्यवहार यह है कि जब हम GetRandomStringsQueryHandler से सुपर क्लास को हटाते हैं और निष्पादन समारोह से "ओवरराइड" संशोधक को हटाते हैं तो कोई स्मृति रिसाव नहीं होगा और ऐप ठीक काम करेगा!

क्या कोई इस व्यवहार को समझा सकता है? यह मेरी गलती या तेज मुद्दा है?

मैं तेजी से 2.

+0

आप कैसे निर्धारित करने कर रहे हैं एक स्मृति रिसाव है? क्या आप एक असली डिवाइस पर चल रहे हैं जो स्मृति से बाहर हो रहा है और दुर्घटनाग्रस्त हो रहा है? या केवल उपकरणों के साथ पुष्टि? और जब आप उपकरणों में पुष्टि करते हैं, तो क्या आप असली डिवाइस या सिम्युलेटर का उपयोग कर रहे हैं? और किसी भी तरह से, लीकिंग के रूप में क्या स्मृति की सूचना दी जा रही है? – nhgrif

+0

अभी जब मैं ऐप चलाता हूं तो मुझे अपवाद मिलता है: libswiftCore.dylib'_swift_release_ (swift :: HeapObject *) में EXC_BAD_ACCESS: डिवाइस के संबंध में मैं सिम्युलेटर का उपयोग कर रहा हूं। – razor118

+0

यह एक स्मृति रिसाव से थोड़ा अलग है और शायद आपके प्रश्न में जोड़ा जाना चाहिए। – nhgrif

उत्तर

2

दिलचस्प सवाल के साथ Xcode के अंतिम verion का उपयोग कर रहा हूँ! मैंने आपके कोड को खेल के मैदान में चिपकाया और आपके सामने आने वाली त्रुटि को पुन: उत्पन्न करने में कामयाब रहा। मैंने कोड को ट्विक करने की कोशिश की लेकिन जेनेरिक काम करने में असफल रहा। एक विकल्प के रूप में, मैं बाधाओं को व्यक्त करने के लिए प्रोटोकॉल का उपयोग कर कोड को फिर से लिखना समाप्त करता हूं।

कोर प्रोटोकॉल:

protocol QueryType { 
    typealias ResultType 
} 

protocol QueryHandler { 
    typealias Query: QueryType 
    func execute(query: Self.Query, callback: (result: Self.Query.ResultType) -> Void) 
} 

अनुरूप कक्षाएं:

class GetRandomStringsQuery: QueryType { 
    typealias ResultType = [String] 

    internal var prefix:String 

    init(prefix: String) { 
     self.prefix = prefix 
    } 
} 


class GetRandomStringsQueryHandler: QueryHandler { 

    func execute(query: GetRandomStringsQuery, callback: (result: [String]) -> Void) { 
     var result = [String]() 

     for var i = 0; i < 100; i++ { 
      result.append("[\(i)]: \(query.prefix)") 
     } 

     callback(result: result) 
    } 

} 

कॉलिंग कोड:

let query = GetRandomStringsQuery(prefix: "leak leak leak :(") 

let queryHandler = GetRandomStringsQueryHandler() 

queryHandler.execute(query) { (result) -> Void in 
    print("total records: \(result.count)") 
} 
+0

+1। केवल एक चीज है कि मुझे लगता है कि आप GetRandomStringsQueryHandler –

+0

पर अपने टाइपलाइज़ को परिभाषित करना भूल गए हैं, मुझे लगता है कि संकलक अनुमान लगा सकता है कि मैंने निष्पादन विधि के लिए तर्क के रूप में क्या पारित किया है।अन्यथा यह प्रोटोकॉल अनुरूपता के साथ एक मुद्दा उठाएगा। –

+0

हाय, उस समस्या के लिए प्रोटोकॉल विकल्प बनाने के लिए धन्यवाद। मुझे उम्मीद है कि जेनेरिक तय किया जाएगा। – razor118

संबंधित मुद्दे