2016-12-21 12 views
14

बनाता है मेरे पास UINavigationController और UITableViewController के उप-वर्ग हैं।UINavigationController subclass की सुविधा प्रारंभिकता subclass निरंतर init दो बार

उप-वर्गों को प्रारंभ करने के लिए मैंने कुछ convenience init विधियों का उपयोग करने का निर्णय लिया जो सुपरक्लास के कुछ निर्दिष्ट प्रारंभकर्ता को कॉल करते हैं।

let someValue: SomeClass = SomeClass() 

प्रत्येक वर्ग सफलतापूर्वक अपने नव निर्मित convenience init विधि को फोन करके आरंभ नहीं हो जाता: इसके अलावा, प्रत्येक उपवर्ग कुछ let निरंतर है।

समस्या यह है कि let निरंतर UINavigationController उपवर्ग में दो बारआरंभ नहीं हो जाता है।

import UIKit 
import PlaygroundSupport 

final class Navigation: UINavigationController { 
    convenience init(anyObject: Any) { 
     self.init(rootViewController: UIViewController()) 
    } 
    let service = Constant("Constant Initialization -> Navigation") 
} 

final class Table: UITableViewController { 
    convenience init(anyObject: Any) { 
     self.init(style: .plain) 
    } 
    let service = Constant("Constant Initialization -> Table") 
} 

class Constant: NSObject { 
    init(_ string: String) { 
     super.init() 
     debugPrint(string) 
    } 
} 

Navigation(anyObject: NSNull()) 
Table(anyObject: NSNull()) 

क्या हमें ऊपर की तरह convenience init का उपयोग करने की अनुमति है? क्यूं कर?

इन दो मामलों में convenience init व्यवहार अलग क्यों है?

साथ जांचा गया: संस्करण 8.2 बीटा (8C30a), संस्करण 8.2 (8C38), संस्करण 8.2.1 (8C1002)

पी.एस. उपरोक्त कोड का खेल का मैदान लॉग:

"Constant Initialization -> Navigation" 
"Constant Initialization -> Navigation" 
"Constant Initialization -> Table" 

उत्तर

3

तो यह स्विफ्ट के साथ अजीब "अपेक्षित व्यवहार" प्रतीत होता है। ऐसा होने का कारण निरंतर आरंभिक संपत्ति service के कारण है। अर्थात्, इस पोस्ट मुद्दा अपने बहुत अच्छी तरह से देख रहा सार रखते हैं: blog post

अनिवार्य रूप से, Obj सी अंतर्निहित सुपर वर्गों लीक कर रहे हैं स्मृति और अपने service संपत्ति Obj सी प्रारंभ की इस पद्धति की वजह से दो बार आरंभ नहीं हो जाता:

- (id)init { 
    self = [super init]; 
    if (self) { 
    self = [[self.class alloc] initWithNibName:nil bundle:nil]; 
    } 
    return self; 
} 

इस से बचने के लिए एक सरल समाधान निम्नलिखित पैटर्न है:

import UIKit 

final class NavigationController: UINavigationController { 
    var service: ObjectTest? 

    convenience init() { 
     self.init(rootViewController: UIViewController()) 
     self.service = ObjectTest("init nav") 
    } 
} 
class ObjectTest: NSObject{ 
    init(_ string: String) { 
     super.init() 
     print(string) 
    } 
} 

सब अपने कार्यान्वयन से बदल रहा है के बाद ही service आरंभ कर रहा है यो यूआर क्लास ही शुरू किया गया है।

एक और समाधान, हालांकि, आरंभिक सुपरक्लास के लिए नामित प्रारंभकर्ता का उपयोग करना है। मतलब यह है कि आप सुविधा प्रारंभकर्ता का उपयोग नहीं करते हैं जो उपरोक्त ओब्जे-सी प्रारंभिक पैटर्न को नियोजित करेगा।

+0

आपके उत्तर के लिए धन्यवाद। और मुझे अभी भी समझ में नहीं आ रहा है कि उन दो मामलों में सुविधा init व्यवहार अलग क्यों है? – iWheelBuy

+0

तो 'सुविधा' प्रारंभिक उपरोक्त उद्देश्य-सी उदाहरण init पैटर्न का उपयोग करता है, जहां दो इनिट कॉल (' [सुपर init] 'और '[self.class alloc] init ...]' नामित प्रारंभिक, मेरे द्वारा नामित प्रारंभकर्ता समझदारी, सीधे '[self.class alloc] init ...]' प्रारंभकर्ता पथ में जायेगी, और इसलिए प्रारंभिक दोगुनी नहीं होगी, जो आप देख रहे मुद्दे का कारण बनती है। – BHendricks

+0

मैंने सोचा है कि दोनों मामलों में मैं नामित प्रारंभकर्ता कहता हूं, है ना? – iWheelBuy

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